最近项目上让使用pinia状态管理,初步记录一下学习情况。
在Vue3中,尤大神也是推荐我们使用pinia来实现状态管理,他也说pinia就是Vuex的新版本。
在粗略学习,pinia比vuex少了Mutation。并且对ts有良好的支持,喜欢ts得小伙伴可以上手了
安装pinia
yarn add pinia
# 或者使用 npm
npm install pinia
使用pinia
main.js
createPinia 创建pinia
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import { createPinia } from "pinia";
import 'windi.css'
const app = createApp(App)
const pinia = createPinia();
pinia.use(({store})=>{
const initialState = JSON.parse(JSON.stringify(store.$state));
store.$reset = ()=>{
store.$state = JSON.parse(JSON.stringify(initialState));
}
});
app.use(pinia)
app.use(router)
app.mount("#app");
创建store defineStore
store简单来说就是数据仓库的意思,我们数据都放在store里面,pinia通过defineStore()创建一个仓库,第一个参数是唯一ID,第二个参数是一个options配置项或者组件式API
下面,使用配置式创建和组合式得创建,
import { defineStore } from "pinia";
import {ref,computed} from 'vue'
//vue 配置式
export const useUsersStore = defineStore("users",{
state: () => {
return { count: 2 }
},
getters:{
doubleCount:(state) => {
return state.count * 2;
},
},
actions: {
addCount() {
this.count++
}
}
})
//vue 组合式API
export const usePatientStore = defineStore('patients',()=>{
const age = ref(20)
const name = ref('组合式')
const doubleAge = computed(()=> age.value * 2)
function addAge() {
age.value++
}
return { name,age,doubleAge, addAge }
})
组件内使用store
import {usePatientStore, useUsersStore} from '@/store'
const store = usePatientStore()
const userStore = useUsersStore()
这里,我们就能拿到对应得store,下面我们看看store都有什么
我们定义得属性和方法都在这里
使用state
读取state
我们通过解构可以直接获取到属性,但是这样获取到得数据并不式响应式的,因此pinia也为我们提供了相应的方法 storeToRefs()
import { storeToRefs } from 'pinia'
import {usePatientStore, useUsersStore} from '@/store'
import {ref} from 'vue'
const mesg = ref('我是Atest')
const store = usePatientStore()
const userStore = useUsersStore()
console.log('userStore',userStore)
//非响应式属性获取
const {age,doubleAge } = store
//响应式属性的获取
const {age,doubleAge} = storeToRefs(store)
修改state
修改state,我们可以直接store.age进行修改,也可以使用$patch进行修改
store.$patch((state) => {
state.age = 12
})
//整体修改
store.$patch({
age:12
})
重置state $reset()
重置为最初始的状态
在使用重置时,遇见了一个小问题,就是我通过使用组合式API方式创建的store,在重置时回报错,需要在main.js里添加这个就可以使用reset(),如果时配置式的不回出现此问题
const pinia = createPinia();
pinia.use(({store})=>{
const initialState = JSON.parse(JSON.stringify(store.$state));
store.$reset = ()=>{
store.$state = JSON.parse(JSON.stringify(initialState));
}
});
app.use(pinia)
组件内使用重置
const restState = ()=> {
console.log('开始重置')
store.$reset()
userStore.$reset()
}
替换state $state
const store = usePatientStore()
const userStore = useUsersStore()
console.log('userStore',userStore)
store.$state = {
age:9999
}
总结
pinia其实和vuex的用法其实都差不多,如果有vuex的基础,大致看一遍就能上手,我这里也是把pinia的state 、 getters、actions 介绍了一下。具体详情这些还是要看官方文档。
完整列子代码
<template>
<div>
{{mesg}}
</div>
<div class="age">
<p>{{age}}</p>
<p>双倍年龄{{doubleAge}}</p>
<button @click="addAge">年龄加1</button>
<p>{{count}}</p>
<p>双倍快乐{{doubleCount}}</p>
<button @click="count++">count++</button>
<button @click="restState">重置年龄state的数据</button>
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import {usePatientStore, useUsersStore} from '@/store'
import {ref} from 'vue'
const mesg = ref('我是Atest')
const store = usePatientStore()
const userStore = useUsersStore()
console.log('userStore',userStore)
// store.$state = {
// age:9999
// }
//非响应式属性获取
//const {age,doubleAge } = store
//响应式属性的获取
const {age,doubleAge} = storeToRefs(store)
const {count,doubleCount} = storeToRefs(userStore)
//函数的获取
const {addAge} = store
const restState = ()=> {
console.log('开始重置')
store.$reset()
userStore.$reset()
}
</script>
<style scoped lang="scss">
.age {
width: 200px;
height: 200px;
margin: 0 auto;
background-color: #42b983;
}
</style>