,Pinia ,发音为 /piːnjʌ/,来源于西班牙语 piña 。意思为菠萝,表示与菠萝一样,由很多小块组成。在 Pinia 中,每个 Store 都是单独存在,一同进行状态管理。,Pinia 是由 Vue.js 团队成员开发,最初是为了探索 Vuex 下一次迭代会是什么样子。过程中,Pinia 实现了 Vuex5 提案的大部分内容,于是就取而代之了。,与 Vuex 相比,Pinia 提供了更简单的 API,更少的规范,以及 Composition-API 风格的 API 。更重要的是,与 TypeScript 一起使用具有可靠的类型推断支持。,既然 Pinia 这么香,那么还等什么,一起用起来吧!,安装:,在 main.js 中 引入 Pinia:,在 src/stores 目录下创建 counter.js 文件,使用 defineStore() 定义一个 Store 。defineStore() 第一个参数是 storeId ,第二个参数是一个选项对象:,我们也可以使用更高级的方法,第二个参数传入一个函数来定义 Store :,在组件中导入刚才定义的函数,并执行一下这个函数,就可以获取到 store 了:,这就是基本用法,下面我们来介绍一下每个选项的功能,及插件的使用方法。,store 是一个用 reactive 包裹的对象,如果直接解构会失去响应性。我们可以使用 storeToRefs() 对其进行解构:,除了可以直接用 store.count++ 来修改 store,我们还可以调用 $patch 方法进行修改。$patch 性能更高,并且可以同时修改多个状态。,但是,这种方法修改集合(比如从数组中添加、删除、插入元素)都需要创建一个新的集合,代价太高。因此,$patch 方法也接受一个函数来批量修改:,我们可以通过 $subscribe() 方法可以监听 store 状态的变化,类似于 Vuex 的 subscribe 方法。与 watch() 相比,使用 $subscribe() 的优点是,store 多个状态发生变化之后,回调函数只会执行一次。,也可以监听 pinia 实例上所有 store 的变化。,大多数情况下,getter 只会依赖 state 状态。但有时候,它会使用到其他的 getter ,这时候我们可以通过 this 访问到当前 store 实例。,要使用其他 Store 的 getter,可以直接在 getter 内部使用:,getter 本质上是一个 computed ,无法向它传递任何参数。但是,我们可以让它返回一个函数以接受参数:,在组件中使用:,注意:如果这样使用,getter 不会缓存,它只会当作一个普通函数使用。一般不推荐这种用法,因为在组件中定义一个函数,可以实现同样的功能。,与 getters 一样,actions 可以通过 this 访问当 store 的实例。不同的是,actions 可以是异步的。,要使用其他 Store 的 action,也可以直接在 action 内部使用:,以上就是 Pinia 的详细用法,是不是比 Vuex 简单多了。除此之外,插件也是 Pinia 的一个亮点,个人觉得非常实用,下面我们就来重点介绍一下。,由于是底层 API,Pania Store 完全支持扩展。以下是可以扩展的功能列表: - 向 Store 添加新状态 - 定义 Store 时添加新选项 - 为 Store 添加新方法 - 包装现有方法 - 更改甚至取消操作 - 实现本地存储等副作用 - 仅适用于特定 Store,Pinia 插件是一个函数,接受一个可选参数 context ,context 包含四个属性:app 实例、pinia 实例、当前 store 和选项对象。函数也可以返回一个对象,对象的属性和方法会分别添加到 state 和 actions 中。,然后使用 pinia.use() 将此函数传递给 pinia 就可以了:,可以简单地通过返回一个对象来为每个 store 添加状态:,也可以直接在 store 上设置属性来添加状态,为了使它可以在 devtools 中使用,还需要对 store.$state 进行设置:,也可以在 use 方法外面定义一个状态,共享全局的 ref 或 computed :,可以在定义 store 时添加新的选项,以便在插件中使用它们。例如,可以添加一个 debounce 选项,允许对所有操作进行去抖动:,然后使用插件读取该选项,包装并替换原始操作:,这样在组件中使用 actions 的方法就可以去抖动了,是不是很方便!,相信大家使用 Vuex 都有这样的困惑,F5 刷新一下数据全没了。在我们眼里这很正常,但在测试同学眼里这就是一个 bug 。Vuex 中实现本地存储比较麻烦,需要把状态一个一个存储到本地,取数据时也要进行处理。而使用 Pinia ,一个插件就可以搞定。,这次我们就不自己写了,直接安装开源插件。,然后引入插件,并将此插件传递给 pinia :,接着在定义 store 时开启 persist 即可:,这样,无论你用什么姿势刷新,数据都不会丢失啦!,默认情况下,会以 storeId 作为 key 值,把 state 中的所有状态存储在 sessionStorage 中。我们也可以通过 strategies 进行修改:,ok,今天的分享就是这些。不知道你对 Pinia 是不是有了更进一步的了解,欢迎评论区留言讨论。,Pinia 整体来说比 Vuex 更加简单、轻量,但功能却更加强大,也许这就是它取代 Vuex 的原因吧。此外,Pinia 还可以在 Vue2 中结合 map 函数使用,有兴趣的同学可以研究一下。
© 版权声明
文章版权归作者所有,未经允许请勿转载。