一篇文章足以入门Vue新的状态管理Pinia,并且已经收录在官方github中。有了Vuex,为什么还要再开发一个Pinia?先来一张图,看看当时对Vuex5的提案,下一代的Vuex5应该是这个样子。Pinia完全符合他当时Vuex5提案中提到的功能,所以说Pinia是Vuex5也不为过,因为它的作者是官方开发者,已经被官方接手了,但是目前Vuex和Pinia还是两个独立的仓库,以后可能会合并或者独立开发,但是官方一定要推荐Pinia,因为在Vue3中使用Vuex,在Vuex中需要使用Vuex4,只能作为过渡的选择,其中有很大的缺陷。因此,在CompositionAPI诞生后,设计了新的状态管理PiniaPinia和VuexVuex:State,Gettes,Mutations(同步),Actions(异步)4.xVuex4用于Vue3Vuex3用于Vue2Pinia目前最新版本是2.x,同时支持Vue2和Vue3目前来看,Pinia比Vuex好很多,解决了Vuex的很多问题,所以笔者也强烈推荐使用Pinia直接,特别是TypeScript项目Pinia核心特性Pinia没有MutationsActions支持同步和异步嵌套结构没有模块Pinia在设计上提供了一个扁平化的结构,这意味着每个store都是相互独立的,不属于任何人,即,它被扁平化,代码分割更好,没有命名空间。当然你也可以通过在一个模块中导入另一个模块来隐式嵌套存储,你甚至可以对存储有循环依赖更好的TypeScript支持不再需要创建自定义复杂包装器来支持TypeScript一切都是类型化的,API的设计也尽可能使用TS类型推断。无需注入、导入函数和调用它们。享受自动补全,让我们的开发更加方便。无需手动添加商店,其模块默认自动注册。除了初始安装和SSR配置之外,Vue2和Vue3都支持相同的API。它们支持VueDevTools来跟踪操作,并且可以在使用该模块的组件中观察到变化的时间线。模块本身支持时间。-旅行更容易调试。在Vue2中,Pinia会使用到Vuex的所有接口,所以不能混用。但是对Vue3的调试工具支持并不完善。比如没有穿越功能模块。热更新无需重新加载页面即可修改模块热更新时,将保持任何现有状态。支持插件扩展。支持Pinia功能。Pinia的服务器端渲染。以Vue3+TypeScript为例,安装npminstallpiniamain.ts。从'pinia'createApp(App)初始化配置导入{createPinia}。use(createPinia()).mount('#app')以在store目录下创建一个user.ts为例,我们先定义并导出一个名为user的模块import{defineStore}from'pinia'exportconstuserStore=defineStore('user',{state:()=>{return{count:1,arr:[]}},getters:{...},actions:{...}})defineStore首先有两个参数第一个参数是模块的名称,必须是唯一的。多个模块不能有相同的名称。Pinia会将所有模块挂载到根容器。第二个参数是一个对象,里面的options该项目与Vuex几乎相同。状态用于存储全局状态。它必须是箭头函数。为了避免服务端渲染时交叉请求造成的数据状态污染,只能是函数,为了更好的TS,必须使用箭头函数。类型推导getter用于封装计算属性,具有缓存的功能。Actions用于封装业务逻辑、修改状态和访问状态。比如我们要在页面中访问state中的属性count。因为defineStore会返回一个函数,我们必须先调用它。获取数据对象,然后就可以在模板中直接使用了'../store'constuser_store=userStore()//解构//const{count}=userStore()比如像注释那样解构使用是没有问题的,注意一下,所以你可以得到它数据没有响应。如果你想解构并保持响应,你需要使用一个方法storeToRefs()。示例如下store'const{count}=storeToRefs(userStore)原因是Pinia实际上使状态数据具有反应性。和Vue3的reactive一样,解构出来的是没有responsive的,所以需要做refresponsiveproxygetters,和Vuex的getters一样,也有缓存功能在页面中多次使用如下,第一次会调用getter,如果数据没有变化,后面会读取缓存
跨模块修改数据在一个模块的动作中,需要修改另一个模块的状态数据例子:比如修改用户模块中的某个用户的名字聊天模块//chat.tsim端口{defineStore}来自'pinia'import{userStore}from'./user'exportconstchatStore=defineStore('chat',{actions:{someMethod(userItem){userItem.name='newname'constuser_store=userStore()user_store.updateUserName(userItem)}}})user模块//user.tsimport{defineStore}from'pinia'exportconstuserStore=defineStore('user',{state:()=>{return{list:[]}},actions:{updateUserName(userItem){constuser=this.list.find(item=>item.id===userItem.id)if(user){user.name=userItem.name}}}})结论如果本文对您有帮助如果对你有一点帮助,点个赞支持一下。你们的每一个【点赞】,都是我创作最大的动力。感谢大家的支持^_^扫描二维码关注公众号,可以加我为好友,我拉你进前端交流群,一起交流,共同进步
