Vue3-Pinia-状态管理器
目录
- pinia是什么?
- pinia的核心概念
- pinia 持久化插件
内容一 pinia是什么
概念:
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。在我们开发一个web端系统或者app时,有一些数据需要我们在好多个页面使用,例如 用户的登录信息,用户的权限信息等,这时我们就可以用pinia 将这些信息存在state中,从而实现每个页面都可以使用。
特点:
- 完整的 ts 的支持;
- 足够轻量,压缩后的体积只有1kb左右;
- 去除 mutations,只有 state,getters,actions;
- actions 支持同步和异步;
- 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的;
- 无需手动添加 store,store 一旦创建便会自动添加;
- 支持Vue3 和 Vue2;
- 不再有可命名的模块
内容二 pinia核心概念
定义仓库Store :
Store 是用 defineStore() 来定义,
defineStore() 第一个参数:要求为独一无二的名字,也用作 id ,必须传入;
defineStore() 的第二个参数:可接受两类值:Setup 函数或 Option 对象。Vue 组合式 API 的 setup 函数 相似。本人习惯使用Option (更直观简单),下列展示Option 示例:
import { defineStore } from 'pinia'
export const meStore = defineStore('me', {
state: () => ( { Count: 0 } ),
getters: {
double: (state) => state.Count * 2 ,
},
actions: {
increment() {
this.Count++
}
}
})
可以认为 state 是 store 的数据 (data),getters 是 store 的计算属性 (computed),而 actions 则是方法 (methods)。
使用Store:
<script setup>
import { meStore } from '@/stores/me'
const store = meStore() // 可以在组件中的任意位置访问 `store` 变量 ✨
</script>
一旦 store 被实例化,你可以直接访问在 store 的 state、getters 和 actions 中定义的任何属性。
State
定义State:
state 是 store仓库 的核心,用来定义初始化的值。当state 中值发生改变时,调用其的子组件都会得到相应的更新。
import { defineStore } from 'pinia'
const meStore = defineStore('me', {
state: () => {
return {
name:'月月',
age:18
}
}
})
访问State
在其他组件中访问:
const store = meStore()
console.log('姓名:', store.name)
在Store内部访问(getters / actions):
this.age++
console.log('年龄:', this.age)
修改State
除了用 store.age++ 直接改变 store,你还可以调用 $patch 方法批量修改 。
$patch对象模式:
import { meStore } from '@/stores/me'
const store = meStore()
store.$patch({
name: '哈哈',
age: 19
})
弊端:无法处理逻辑
$patch函数模式:
store.$patch((state) => {
state.items.push({ quantity: 1 })
state.name = '哈哈'
})
可以处理逻辑
-
还可以在
actions写方法修改 再进行调用
actions: {
updateName() {
this.name = '哈哈'
}
}
替换State
$state您可以通过将store的属性设置为新对象来替换store的整个状态。 (覆盖 也可以修改state 不建议)
import { meStore } from '@/stores/me'
const store = meStore()
const Add = () => {
store.$state = {
name:'丫丫',
age:30
}
弊端:必须修改整个对象的所有属性
重置State
$reset() 会把state所有值 重置回 原始状态
const store = meStore()
store.$reset()
侦听 state
$subscribe() 方法侦听 state及值的变化。一变化就会调用这个函数,可在里面做事件。
store.$subscribe((args, state) => {
console.log(args,state);
})
如果你的组件卸载之后还想继续调用请设置第二个参数
store.$subscribe((args, state) => {
console.log(args,state);
},{
detached:true // 卸载之后可继续调用
})
解构 state
根据实例进行解构,不具有响应式,可使用API storeToRefs 将结构出来的值变成响应式。
import { storeToRefs } from 'pinia'
const store = meStore()
const { age, name } = storeToRefs(store)
Getter
Getter 相当于store 的 state 的计算属性。
箭头函数
- 使用箭头函数,它将接收
state作为第一个参数,不能使用this
export const meStore = defineStore('me', {
state: () => {
return{
count: 0,
name:'月月'
}
},
getters: {
doubleCount: (state) => state.count * 2,
}
})
常规函数
- 在使用常规函数定义
getter时,我们也可以通过this访问到整个 store 实例
export const meStore = defineStore('me', {
state: () => {
return {
count: 0
}
},
getters: {
doubleCount():number {
return this.count + 1
}
}
})
互相调用
getters内函数可以互相调用
getters:{
newCurrent ():number | string {
return ++this.count + this.newName
},
newName ():string {
return `$-${this.name}`
}
},
Actions
Actions 相当于组件中的 method,支持同步异步函数。action 也可通过 this 访问整个 store 实例
同步
import { defineStore } from 'pinia'
export const meStore = defineStore(me, {
state: () => {
return {
count: 0
}
},
actions: {
increment() {
this.count++
},
randomizeCounter() {
this.count = Math.round(100 * Math.random())
},
},
})
组件使用
<script setup lang='ts'>
import {meStore} from './me'
const store = meStore()
const Add = () => {
store.randomizeCounter()
}
</script>
异步
- 可以结合
asyncawait修饰
async getLoginInfo() {
const result = await Login()
this.user = result;
}
相互调用
Actions内的方法可相互调用
import { defineStore } from 'pinia'
export const meStore = defineStore(me, {
state: () => {
return {
count: 0
}
},
actions: {
increment() {
this.count++
},
randomizeCounter() {
this.count = Math.round(100 * Math.random())
if(....可写逻辑){
this.increment() // 调用其他方法
}
}
}
})
侦听Actions
- 只要有
actions被调用就会走这个函数
store.$onAction((args)=>{
console.log(args);
})
内容三 pinia持久化插件
pinia 和 vuex 都有一个通病,页面刷新状态会丢失。所以在使用时可搭配pinia持久化插件一起使用。可在插件库搜索符合项目的插件。