pinia@2
介绍
Pinia (发音为
/piːnjʌ/
,类似英文中的 “peenya”) 是最接近有效包名 piña (西班牙语中的 pineapple,即“菠萝”) 的词,是一个状态管理插件,允许跨组件,跨页面共享状态。vuex的升级版,相比于vuex少了一个mutation。下面的内容我将配合vue3的组合式API来演示,推荐使用vue3组合式API,建议通过
pnpm add pinia
来进行安装
基础
配置到项目
在项目中启用pinia
// /src/main.js 文件 import { createPinia } from 'pinia' app.use(createPinia())
注:在此目录下新建
/src/stores/counter.js
文件存放我们的例子,一般来说我们将状态文件放入stores
目录下 选项式写法
import { defineStore } from 'pinia' // 参数一定义的是唯一ID,是必须传入的, Pinia 将用它来连接 store 和 devtools export const useCounterStore = defineStore('counter', { state: () => ({ count: 0 }), getters: { double: (state) => state.count * 2, }, actions: { increment() { this.count++ }, }, })
函数式写法 (记得最后需要返回参数!)
import { defineStore } from 'pinia' // 参数一定义的是唯一ID,是必须传入的, Pinia 将用它来连接 store 和 devtools export const useCounterStore = defineStore('counter', () => { const count = ref(0) function increment() { count.value++ } return { count, increment } })
Tips: 导出的函数一般要带有use前缀,一般都是这样命名的
State
定义一个返回初始状态(对象)的函数
import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', () => { state: ()=> ({ count: 0, // 定义数据 }) })
应用
import { useCounterStore,storeToRefs } from './stores/counter.js' const counterStore1 = useCounterStore() // 每一个useCounterStore都相同 const counterStore2 = useCounterStore() // 两者相等,这不能直接解构,解构会失去响应式 const counterStore3 = useCounterStore() const { count } = storeToRefs(counterStore3) // 可以通过官方方法解构 console.log(++counterStore1.count) // 这里将会非常简单 counterStore1.$reset() // 可以通过调用 store 的 $reset() 方法将 state 重置为初始值。 counterStore1.$patch({ // 同时间给多个属性赋值 count: counterStore1.count + 1, age: 120, name: 'DIO', }) counterStore1.$patch((state) => { // 上面的函数式写法 state.items.push({ name: 'shoes', quantity: 1 }) state.hasChanged = true }) // 订阅这个Store,每当Store的发生了变化,就调用 cartStore.$subscribe((mutation, state) => { // import { MutationType } from 'pinia' mutation.type // 'direct' | 'patch object' | 'patch function' // 和 cartStore.$id 一样 mutation.storeId // 'cart' // 只有 mutation.type === 'patch object'的情况下才可用 mutation.payload // 传递给 cartStore.$patch() 的补丁对象。 // 每当状态发生变化时,将整个 state 持久化到本地存储。 localStorage.setItem('cart', JSON.stringify(state)) })
Getter
就是store => state 的计算值, 通过
defineStore()
中的getters
属性来定义它们。推荐使用箭头函数,并且它将接收state
作为第一个参数// 非常简单,这里就不多讲了,就是vue的计算属性 export const useStore = defineStore('main', { state: () => ({ count: 0, }), getters: { doubleCount: (state) => state.count * 2, }, })
Action
相当于vue中的methods,主要写业务逻辑的
export const useCounterStore = defineStore('main', { state: () => ({ count: 0, }), actions: { increment() { this.count++ }, randomizeCounter() { this.count = Math.round(100 * Math.random()) }, }, })
订阅某个store的action,可以通过
store.$onAction()
来监听 action 和它们的结果。传递给它的回调函数会在 action 本身之前执行。after
表示在 promise 解决之后,允许你在 action 解决后执行一个回调函数。同样地,onError
允许你在 action 抛出错误或 reject 时执行一个回调函数。这些函数对于追踪运行时错误非常有用,类似于Vue docs 中的这个提示const unsubscribe = someStore.$onAction( ({ name, // action 名称 store, // store 实例,类似 `someStore` args, // 传递给 action 的参数数组 after, // 在 action 返回或解决后的钩子 onError, // action 抛出或拒绝的钩子 }) => { // 为这个特定的 action 调用提供一个共享变量 const startTime = Date.now() // 这将在执行 "store "的 action 之前触发。 console.log(`Start "${name}" with params [${args.join(', ')}].`) // 这将在 action 成功并完全运行后触发。 // 它等待着任何返回的 promise after((result) => { console.log( `Finished "${name}" after ${ Date.now() - startTime }ms.\nResult: ${result}.` ) }) // 如果 action 抛出或返回一个拒绝的 promise,这将触发 onError((error) => { console.warn( `Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.` ) }) } ) // 手动删除监听器 unsubscribe()
本文来自博客园,作者:Pro成,转载请注明原文链接:https://www.cnblogs.com/ProCheng/p/17385831.html