一、pinia 特点
体积小、性能好、使用简单、限制少
支持 Vue Devtools、模块热更新、服务端渲染、Vue2 和 Vue3
没有 mutations,只有 state、getters、actions(异步和同步都可)
二、pinia 安装配置
安装
npm install pinia -S
在 main.js 中注册 pinia
import{createPinia}from'pinia'app.use(createPinia())
注意事项
1.pinia 的配置是模块化的,通过defineStore()函数的参数来定义不同模块,通过import导入的方式在组件中使用2.根据defineStore()的参数不同:可以通过选项式的方式定义模块store、也可以通过组合API的方式定义模块store3.在组件中使用 store 中的state数据需要注意:store直接在模板中使用是响应式的,但是如果通过解构的方式使用则不是响应式的,如果一定要解构使用,可以通过storeToRefs(store)函数对 store 进行响应式解构4.在 pinia 中改变 state 的状态,可以直接通过赋值的方式进行改变,没有vuex中只能通过commit修改的限制5.在组件中使用模块store中 state 的数据时直接使用store.的方式,而不是store.state.,使用 getter 也是一样直接 store.6.在组件中使用模块store中 action 方法时直接使用既可,不需要使用模块的名称,因为我们在组件中使用import解构导入store时,已经指定了模块下的store7.pinia 中的 getter 没有缓存效果,相当于调用函数,可传入参数
三、pinia 通过选项方式配置 store
创建 src\stores\a.js 模块配置文件
import{defineStore}from'pinia'exportconstaStore=defineStore({id:'a',state:()=>({a:1,oa:{a:100}}),getters:{ca:(state)=>{returnstate.a*2}},actions:{// actions 同步SYNCA(){this.a=this.a*2},// actions 异步asyncASYNCA(params){constdata=()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{params?resolve(params+1):reject(0)},2000)})}constgetData=awaitdata()this.oa.a=this.oa.a*getData// 如果有部分数据没有在state中定义,但是需要在组件中使用,也可以通过返回 promise 的方式异步处理// return getData}}})
在组件中使用
<template><div><h1>{{useAStore.a}}</h1><h1>{{oa.a}}</h1><h1>{{ca}}</h1><button @click="setSYNCA">setSYNCA</button><button @click="setASYNCA">setASYNCA</button></div></template><script setup>import{aStore}from'@/stores/a.js'import{storeToRefs}from'pinia'constuseAStore=aStore()const{oa,ca}=storeToRefs(useAStore)// 响应式解构数据const{SYNCA,ASYNCA}=useAStorefunctionsetSYNCA(){oa.value.a++// 在组件中,直接通过赋值改变 stateSYNCA(1)}functionsetASYNCA(){ASYNCA(1)// 如果在 action 中,返回了一个 promise 数据,可以使用链式的方式获取数据// ASYNCA(1).then((res) => console.log(res)).catch((err) => console.log(err))}</script>
四、pinia 通过组合 API 方式配置 store
创建 src\stores\a.js 模块配置文件
import{ref,computed,reactive}from'vue'import{defineStore}from'pinia'exportconstaStore=defineStore('a',()=>{// stateconsta=ref(1)constoa=reactive({a:100})// gettersconstca=computed(()=>a.value*2)// actions 同步functionSYNCA(){a.value=a.value*2}// actions 异步asyncfunctionASYNCA(params){constdata=()=>{returnnewPromise((resolve,reject)=>{setTimeout(()=>{params?resolve(params+1):reject(0)},2000)})}constgetData=awaitdata()oa.a=oa.a*getData// 如果有部分数据没有在state中定义,但是需要在组件中使用,也可以通过返回 promise 的方式异步处理// return getData}return{a,oa,ca,SYNCA,ASYNCA}})
在组件中使用
<template><div><h1>{{useAStore.a}}</h1><h1>{{oa}}</h1><h1>{{ca}}</h1><button @click="setSYNCA">setSYNCA</button><button @click="setASYNCA">setASYNCA</button></div></template><script setup>import{aStore}from'@/stores/a.js'import{storeToRefs}from'pinia'constuseAStore=aStore()const{oa,ca}=storeToRefs(useAStore)// 响应式解构数据const{SYNCA,ASYNCA}=useAStorefunctionsetSYNCA(){oa.value.a++// 直接在组件中,通过赋值改变 stateSYNCA(1)}functionsetASYNCA(){ASYNCA(1)// 如果在 action 中,返回了一个 promise 数据,可以使用链式的方式获取数据// ASYNCA(1).then((res) => console.log(res)).catch((err) => console.log(err))}</script>
五、pinia 特色 API
批量修改 store 中的 state
import{aStore}from'@/stores/a.js'aStore.$patch((state)=>{state.items.push({a:100})state.hasChanged=true})
整体替换 store 中的 state
import{aStore}from'@/stores/a.js'aStore.$state={a:1,oa:{a:100}}
网友评论