前言
pinia是新一代的状态管理工具, pinia 去除了 mutations,只有 state,getters,actions
安装
yarn add pinia -S
创建pinia并引入
在src/store文件下新建一个index.js
// src/store/index.js
import { createPinia } from 'pinia'
const store = createPinia()
export default store
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')
使用(创建一个store)
在src/store文件新建一个user.js文件
import { defineStore } from 'pinia'
// defineStore方法第一个参数是该store的id,必须唯一
const useUserStore = defineStore('userStore', {
// state的值必须是一个函数返回一个对象,这里我们使用箭头函数加小括号的方式省略了return
state: () => ({
name:''
}),
// pinia中没有mutations,可以直接在actions中更改state的值,其中可以直接通过this.xxx获取到state的值
actions:{
updateName(name){
this.name = name
}
}
})
export default useUserStore
在组件中获取state
<template>
<p>{{ name }}</p>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import useUserStore from '@/store/user.js'
const store = useUserStore()
// 1.直接获取
const name = store.name
// 2.结合计算属性获取
const name = computed(()=> store.name)
// 3.另外也可以使用解构获取,但是解构会使其失去响应性,这个时候可以用到pinia的storeToRefs方法
const { name } = storeToRefs(store)
// 以上展示了三种获取state的方式,复制代码注意变量重复
</script>
修改state
修改state也有几种方式:
1.直接修改,不推荐
<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()
function changeName(){
store.name = 'xxx'
}
</script>
2.使用$patch修改数据
<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()
function changeName(){
// 使用$patch修改也有两种方式
// 第一种 $patch方法
store.$patch({
name:'xxx'
})
// 第二种 $patch方法
store.$patch((state) => {
state.name = 'xxx'
})
// 这两种方法对比,推荐第二种,第二种修改state更灵活,且不易出错
}
</script>
3.使用actions中的方法修改数据-推荐
<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()
function changeName(){
store.updateName('xxx')// 这里使用我们上文在actions中定义的updateName方法
}
</script>
getters
getters就比较简单了
import { defineStore } from 'pinia'
const useUserStore = defineStore('userStore', {
state: () => ({
name:'李'
}),
getters: {
fullName: (state) => {
return state.name + '四'
}
}
})
export default useUserStore
<script setup>
import useUserStore from '@/store/user.js'
const store = useUserStore()
const fullName = store.fullName
</script>
actions
actions支持async/await异步写法,也可以调用其他actions方法,也可以调用其他store中的actions方法
// src/store/app.js
import { defineStore } from 'pinia'
const useAppStore = defineStore('appStore', {
actions: {
setData() {
consoloe.log('app')
}
}
})
export default useAppStore
// src/store/user.js
import { defineStore } from 'pinia'
import useAppStore from './app'
import api form '@/request/api'
const useUserStore = defineStore('userStore', {
actions: {
async login(e) {
const { data } = await api.login(e)
this.successFn()// 调用其他actions方法
const appStore = useAppStore()
appStore.setData(data) // 调用 appStore 里的 action 方法
return data
},
successFn(){
console.log('成功')
}
}
})
export default useUserStore
数据持久化
无论是vuex还是pinia,刷新页面都会丢失state中的动态数据 但是我们可以使用插件pinia-plugin-persist轻松实现数据持久化
安装
yarn add pinia-plugin-persist -S
使用
import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'
const store = createPinia()
store.use(piniaPluginPersist)
export default store
在需要持久化的store中开启persist
export const useUserStore = defineStore('userStore',{
state: () => ({
name:'李',
age:18,
gender:'男'
}),
// 数据持久化
persist: {
enabled: true //开启数据缓存
strategies: [
{
key: 'my_user',//自定义key,如果不写,在缓存的key就为defineStore第一个参数名
storage: localStorage,// 获取为sessionStorage
paths: ['name', 'age']// 定义部分字段缓存
}
]
}
})