Vue3已经发布了一段时间,它采用了新的响应式系统,并构建了新的CompositionAPI。Vue的周边生态正在加紧适配这个新系统,官方的状态管理库Vuex也在适配中。为此,官方提出了Vuex5的新提案,支持两种语法创建Store:OptionsApi和CompositionApi;删除突变,只支持状态、吸气剂、动作;模块化设计,可以很好的支持代码拆分;没有嵌套模块,只有Store的概念;完整的TypeScriptUpvoted;该提案下方有一条有趣的评论。简单翻译:巧合的是,Vuex5提案与Pinia实现的功能没有任何关系,只能说是一模一样。今天的文章就给大家介绍一下这款菠萝。在现有项目中安装,使用以下命令安装Pinia模块。#yarnyarnaddpinia@next#npmnpmipinia@next安装完成后,需要在vue3项目的入口文件中导入安装。//main.jsimport{createApp}from'vue'import{createPinia}from'pinia'importAppfrom'./App.vue'//实例化Vueconstapp=createApp(App)//安装Piniaapp.use(createPinia())//挂载到真正的DOMapp.mount('#app')使用Pinia,只需要定义一个store,然后在使用的地方导入数据即可。defineStoreimport{defineStore}from"pinia"//对外暴露一个use方法,会导出我们定义的stateconstuseCounterStore=defineStore({//每个store的id必须是唯一的id:'counter',//state表示数据源state:()=>({count:0}),//getters类似于computed,可以对state值进行二次计算getters:{double(){//getter中的this指向👉statereturnthis.count*2},//使用箭头函数会导致this指向有问题//可以在函数的第一个参数中获取statedouble:(state)=>{returnstate.count*2}},//actions用于修改stateactions:{increment(){//action中的this指向👉statethis.count++},}})exportdefaultuseCounterStore除了使用上面提到的类vuex方法来buildstate,也可以使用function来创建store,有点类似于Vue3中的setup()。import{ref,computed}from"vue"import{defineStore}from"pinia"//对外暴露一个use方法,会导出我们定义的状态constuseCounterStore=defineStore('counter',function(){constcount=ref(0)constdouble=computed(()=>count.value*2)functionincrement(){count.value++}return{count,double,increment}})exportdefaultuseCounterStore在使用Store之前也介绍过,Pinia提供了两种Store的使用方式,Options完美支持Api和CompositionApi。OptionsApi在OptionsApi中,可以直接使用官方提供的mapActions和mapState方法导出store中的state、getter、action。它的用法与Vuex基本相同,上手简单。import{mapActions,mapState}from'pinia'import{useCounterStore}from'../model/counter'exportdefault{name:'HelloWorld',computed:{...mapState(useCounterStore,['count','double'])},methods:{...mapActions(useCounterStore,['increment'])}}CompositionApi在CompositionApi中,无论是state还是getter,都需要通过computed方法来监听变化。这个和OptionsApi中一样,需要放在computed对象中。另外,可以直接修改OptionsApi中获取的state值。当然,还是建议写一个操作state值的action,方便后期维护。//CompositionApiimport{computed}from'vue'import{useCounterStore}from'../stores/counter'exportdefault{name:'HelloWorld',setup(){constcounter=useCounterStore()return{//state和getter需要在使用computed,与OptionsApi相同count:computed(()=>counter.count),double:computed(()=>counter.double),increment:()=>{counter.count++},//可以直接修改state的值increment:counter.increment,//可以参考store中定义的action}}}typehint在Vuex中,TypeScript的typehint做的不是很好,只能找到它的statewhen执行类型推导。尤其是在写代码的过程中,代码提示非常不智能。而pinia可以推导出所有定义的状态、getter、动作,这样写代码的时候会方便很多。主要原因是pinia通过TypeScript有一个非常友好的类型定义。有兴趣的可以看看pinia的类型定义文件(pinia.d.ts):代码切分采用模块化设计,所有的store都可以单独导入,而不像vuex把所有的模块都挂载到一个store上通过模块。假设我们当前通过Vuex创建了一个Store,这个Store下面有两个模块,分别是用户模块(User)和商品模块(Goods)。即使当前首页只使用用户信息,整个Store也会被打包到首页的jschunk中。如果我们使用pinia,我们将使用defineStore来定义两个完全独立的store,两个页面导入时不会互相影响。最后打包的时候,首页的jschunk和商品页的jschunk会分别打包对应的店铺。Pinia的介绍到这里就告一段落了。如果有新项目要使用Vue3开发,推荐使用无脑Pinia,更加简洁,大小只有1KB。
