Pinia.js 是新一代的状态管理器
Pinia.js 的特点:
Vue2 和 Vue3 都能支持
足够轻量,压缩后的体积只有1.6kb;
抛弃传统的 Mutation ,只有 state, getter 和 action ,简化状态管理库
actions 支持同步和异步;
不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化
TypeScript支持
代码简介,很好的代码自动分割
无需手动添加 store,store 一旦创建便会自动添加;
安装:
yarn add pinia
# 或者使用 npm
npm install pinia
创建 Store:
main.js:
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
State
定义State:
在 src/store 下面创建一个user.js
import { defineStore } from'pinia'
export const useUserStore = defineStore({
id: 'user',
state: () => {
return {
name: '无忧'
}
}
})
获取 state:
<template>
<div>{{ userStore.name }}</div>
</template>
<script setup>
import { useUserStore } from'@/store/user'
const userStore = useUserStore()
</script>
也可以结合 computed 获取。
const name = computed(() => userStore.name)
state 也可以使用解构,但使用解构会使其失去响应式,这时候可以用 pinia 的 storeToRefs。
import { storeToRefs } from 'pinia'
const { name } = storeToRefs(userStore)
修改 state
1.可以像下面这样直接修改 state,但一般不建议这么做
userStore.name = '无忧2'
2.通过 actions 去修改 state,action 里可以直接通过 this 访问。
exportconst useUserStore = defineStore({
id: 'user',
state: () => {
return {
name: '无忧'
}
},
actions: {
updateName(name) {
this.name = name
}
}
})
<script setup>
import { useUserStore } from'@/store/user'
const userStore = useUserStore()
userStore.updateName('无忧2')
</script>
3.通过 $patch 去修改 state:
$patch 方法可以接受两个类型的参数,函数 和 对象
<script setup>
import { useUserStore } from'@/store/user'
const userStore = useUserStore()
//对象
userStore.$patch({
name:'无忧2'
})
//函数
userStore.$patch((state)=>{
state.name='无忧2'
})
</script>
重置 state
你可以通过调用 store 的 $reset() 方法将 state 重置为初始值。
<script setup>
import { useUserStore } from'@/store/user'
const userStore = useUserStore()
userStore.$reset()
</script>
Getters
exportconst useUserStore = defineStore({
id: 'user',
state: () => {
return {
name: '无忧'
}
},
getters: {
fullName: (state) => {
return '姜'+state.name
}
}
})
userStore.fullName// 姜无忧
Actions
异步 action
export const useUserStore = defineStore({
id: 'user',
actions: {
async getUserLoad() {
const { data } = await getUserApi()
return data
}
}
})
action 间相互调用
action 间的相互调用,直接用 this 访问即可。
exportconst useUserStore = defineStore({
id: 'user',
actions: {
async getUserLoad() {
const { data } = await getUserApi()
this.setData(data) // 调用另一个 action 的方法return data
},
setData(data) {
console.log(data)
}
}
})
在 action 里调用其他 store 里的 action 也比较简单,引入对应的 store 后即可访问其内部的方法了。
// src/store/user.js
import { useMenuStore } from'./menu'
export const useUserStore = defineStore({
id: 'user',
actions: {
async getUserLoad() {
const { data } = await getUserApi()
const appStore = useMenuStore()
appStore.setData(data) // 调用 menu store 里的 action 方法
}
}
})
// src/store/menu.js
export const useMenuStore = defineStore({
id: 'menu',
actions: {
setData(data) {
console.log(data)
}
}
})