【vue3生态Pinia之State、Getters、Actions详解】
涉及内容:$reset()重置、$patch修改、$state更换、$subscribe订阅、getter:state中的computed、Actions:相当于组件中的 methods、订阅actions、销毁订阅、访问其他Store。Getters1- Getter 完全等同于Store里的state的computed值。2- 他们接收state作为第一个参数,鼓励使用箭头函数功能:3- 外部
本章节请配合`Pinia快速上手章节`该文章食用,下列内容会结合该文章内的例子进行讲解,标红部分表示该文章内容
没基础的,请先看上一篇Pinia文章,这样对这篇的内容会更方便理解。
前情提要:
- 不讲多store互相使用(看上个文章);
- 如果有些你觉得我讲了你看不懂,请先看上一篇文章,太基础的或上一篇已有的这里则会没讲!
# State
大多数时候,`state` 是一个 Store 的主要部分。通常从定义 state 开始,代表vue实例的Store应用。
1. 定义、使用 state 见上一篇文章
2. 重置state数据:
您可以通过调用 store 上的方法将状态重置为其初始值:$reset()
const store = useStore()
store.$reset()
3. 修改state数据:
store.property = xxxx
store.$patch({}) // 或者这样,这种可以统一多个修改
store.$patch((state)=>{ /** 这里修改state */ }) // $patch 方法还接受一个函数,用于应对复杂数据的修改过程
4. 更换state:
$state您可以通过将商店的属性设置为新对象来替换Store的整个状态:
store.$state = { counter: 666, name: 'Paimon' }
5. 订阅state:
store.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// same as cartStore.$id > store 的 name
mutation.storeId // 'cart'
// only available with mutation.type === 'patch object'
mutation.payload // patch object passed to cartStore.$patch()
// 无论何时更改,都将整个状态保留到本地存储 > persist the whole state to the local storage whenever it changes
localStorage.setItem('cart', JSON.stringify(state))
},{ detached: false })
// detached 默认是false,表示当组件被卸载时,$subscribe 订阅将被自动删除。
// 如果要在组件卸载后保留 $subscribe 订阅,则改为 true 以从当前组件中分离状态订阅:
# Getters
声明、使用的案例见3. 4.
1- Getter 完全等同于Store里的state的computed值。
2- 他们接收state作为第一个参数,鼓励使用箭头函数功能:
3- 外部(组件)将参数传递给 getter >>> 见下面代码的 getUserById
4- 访问其他store的getters
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
// 类型是自动推断的,因为我们没有使用 this >> type is automatically inferred because we are not using `this`
// 自动将返回类型推断为number >> automatically infers the return type as a number
doubleCount(state) {
return state.counter * 2
},
// 必须显式设置返回的数据类型
doublePlusOne(): number {
// 整个store的自动完成和typings(不知道咋翻译) >> autocompletion and typings for the whole store ✨
return this.counter * 2 + 1
// 与计算属性一样,您可以组合多个 getter。通过 this 访问任何其他 getter
// return this.doubleCount * 2 + 1
},
getUserById: (state) => {
// Getter只是在幕后计算的属性,因此不可能将任何参数传递给它们。但是,您可以从getter返回一个函数以接受任何参数:
// 请注意,执行此操作时,getter 不再缓存,它们只是您调用的函数。但是,您可以在 getter 本身内部缓存一些结果,这并不常见,但应该证明性能更高: 这段话的功能,要用再去参考官网
return (userId) => state.users.find((user) => user.id === userId)
},
// 要使用其他store 的 getter,您可以直接在getter内部使用它:
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})
上面的功能3演示
<template>
<p>User 2: {{ getUserById(2) }}</p>
</template>
<script>
export default {
setup() {
const store = useStore()
store.counter = 3
console.log(store.doubleCount) // 6 >> 跟state一样,可直接访问。
return {
getUserById: store.getUserById
}
},
}
</script>
# Actions
Actions 相当于组件中的 methods。
1- 你也可以完全自由地设置你想要的任何参数并返回任何东西。调用actions时,一切都会自动推断!
2- 访问其他store的actions等内容;
3- 订阅actions;
传递给订阅的回调比actions事件先一步执行。
默认情况下,actions订阅绑定到添加它们的组件(如果Store位于组件内部setup()里)。意思是,当组件被卸载时,它们将被自动删除。如果要在卸载组件后保留它们,传入第二个参数 true 用以将actions订阅与当前组件分离。
import { useAuthStore } from './auth-store'
export const useSettingsStore = defineStore('settings', {
state: () => ({
// ...
}),
actions: {
fetchUserPreferences(preferences) {
const auth = useAuthStore()
console.log(auth)
},
},
})
订阅actions
export default {
setup() {
const someStore = useSomeStore()
const unsubscribe = someStore.$onAction(
({
name, // name of the action
store, // store instance, same as `someStore`
args, // array of parameters passed to the action
after, // hook after the action returns or resolves
onError, // hook if the action throws or rejects
}) => {
// a shared variable for this specific action call
const startTime = Date.now()
// this will trigger before an action on `store` is executed
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// this will trigger if the action succeeds and after it has fully run.
// it waits for any returned promised
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// this will trigger if the action throws or returns a promise that rejects
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
// 可手动销毁订阅 manually remove the listener
unsubscribe()
// ...
},
}
Pinia是刚学几小时,相关例子不是特别丰富,但功能还是表述出来了和简单的写了。自己也多动手敲!!
Pinia 进阶的 Plugins 后续会再写一篇文章进行讲解。
QQ交流群:522976012 ,欢迎来玩。
聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。
更多推荐
所有评论(0)