最近瞅了一眼Pinia的文档,感觉挺不错的,抛去了vuex里面繁琐的mutations操作,让代码负担减少了很多。
我们知道使用vuex的时候,设置了变量,还得在mutations里通过state.XXX来对变量进行同步操作,当遇到异步操作,还得在actions里调用mutations的方法修改变量,因为vuex是单一状态树,module,namespace这些让我们能够用this.$store.state.moduleA.XXX来获得变量,一套写下来,繁琐哦~
Pinia做了什么改变呢?它就如我们想要的那要,将一个store里变成了类似于data、computed和methods的集合,这不就够了么。因此,pinia最重要的三块就是,state(即data),getters(即computed),actions(即methods)。看个官网的例子:
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => {
return { count: 0 }
},
getters: {
double: (state) => state.count * 2,
},
// could also be defined as
// state: () => ({ count: 0 })
actions: {
increment() {
this.count++
},
},
})
defineStore函数的第一个参数是唯一ID,其实就取文件名就行了,第二个参数为一个对象,里面包含上述的三个模块,在vue文件里使用也很简单:
import { useCounterStore } from '@/stores/counter'
export default {
setup() {
const counter = useCounterStore()
counter.count++
// with autocompletion ✨
counter.$patch({ count: counter.count + 1 })
// or using an action instead
counter.increment()
},
}
如果store里定义了很多属性想通过解构拿到,可以用storeToRefs()。
import { storeToRefs } from 'pinia';
.....
const { count } = storeToRefs(store)
cons {increment} = store; // actions里的方法可以直接解构
修改数据很简单,可以直接store.xxx进行修改,可以通过调用actions的方法修改,也可以用store.$patch({count: store.count+1})。
但是我觉得最好不要直接修改state的值,这样对于项目的管理不友好,统一通过actions的函数进行修改,才能更规范。
翻译一下官网上Pinia相比于Vuex 3.x/4.x的区别(3.x是vue2版本,4.x是vue3版本):
1、mutations去掉了,这玩意非常啰嗦;
2、对TS很好的支持,像在getters里,很多时候可以自动推算出类型;
3、不需要花里胡哨的dispatch或者mapActions辅助函数,直接解构引入函数,调用就行;
4、可以用很多个store,不需要手动添加,这些都是创建即注册的;
5、没有模块和嵌套结构,没有命名空间,pinia提供的是扁平结构,每个store相互独立,一个store里面可以引用另一个store甚至可以构成循环依赖;
6、可以同时支持composition api和options api,SSR,webpack代码拆分。
对于中小型项目,pinia简单轻巧,足够覆盖很多业务场景。我觉得工具的出现,旨在用更少的代码去做更多的事情,这才是轮子创新的意义。