-
Pinia
-
初衷设计
-
设计一个拥有组合式API的Vue状态管理库
-
-
优势
-
Devtools支持
-
热更新
-
插件:可通过插件扩展Pinia功能
-
提供TypeScript支持以及自动功能补全
-
支持服务端渲染
-
-
核心概念
-
定义Store
-
defineStore import {defineStore} from 'pinia'
-
defineStore(arg1, options)
-
arg1: 名字,同时也被用作id,required,id将被用作连接store和devtools
-
options: 接受两类值:Setup函数 或者 Option对象
-
Opition对象 { state: {}, getters: {}, actions: {} }
-
Setup函数: 类似Vue setup函数 () => { return { ...props } } 其中: ref()就是state属性 computed()就是getters function() 就是actions 注意:不能在store中使用私有属性,因为必须返回state属性pinia才能正确是识别state
-
store是一个用reactive包装的对象。不能对它进行解构,结构会失去响应性的连接
-
解决办法:使用 storeToRefs() import { storeToRefs } from 'pinia' const store = userCounterStore() const { name, doubleCount } = storeToRefs(store) 对应action的方法可以直接解构 const { increment } = store
-
-
-
-
-
State const store = useStore() const count = store.count
-
在Pinia中, state被定义为一个返回初始状态的函数。推荐使用箭头函数,获取完整类型推理
-
TypeScript支持
-
访问state const state = store.state
-
重置state
-
使用选项时API store.$reset() 将store重置为初始值
-
辅助函数:mapState / mapWrittableState
-
import { mapState } from 'pinia' 通过mapState可以state属性映射为 只读的计算属性
-
impor { mapWrittableState } from 'pinia' 映射为一个可以修改的属性 computed { ... mapWrittableState(useCounterStore, ['count]) ...mapWrittableState(useCounterStore, { myOwnName: 'count' } }
-
mapWrittable 不能像 mapstate 传递一个函数
-
-
在Setup Store中,需要创建自己的$reset()方法 export const useCounterStore = defineStore('counter', () => { const count = ref(0) function $reset() { count.value = 0 } return { count, $reset } })
-
-
变更state
-
直接修改属性:store.count = 1
-
$patch在同一时间修改多个属性,接受一个state的补丁对象 store.$patch({ count: store.count + 1, age: 120, name: 'DIO' })
-
$patch接受一个函数修改多个属性 store.$path(() =>{ state.item.push({ name: 'shoes', quantity: 1 }) state.hasChange = true })
-
-
替换state
-
使用$patch()替换state对象 store.$patch({count: 24}) store.$state = { count: 24 } 实际并没有替换$state 不能完全替换掉store的state,这样会破坏其响应性
-
-
订阅state
-
可以使用store.$subscribe() 方法侦听state及其变化。 store.$subscribe((mutation, type) => { mutation.type // direct | patch object / patch function mutation.storeId // 注册的store的name mutation.payload // 传递给store.$patch()的补丁对象 // 每当状态发生变化时,将整个state持久化道本地 localStorage.setItem('car', JSON.stringify(state)) })
-
默认情况下,state subscription 会被绑定到添加他们的组件上,组件卸载时会被自定删除 问题解决:可以通过$subscribe(callbakc, {detached: true})的第二个参数 detached设置为true, 可以将subcription 从当前组件分离,组件卸载之后然后会被保留
-
可以使用pinia实例上使用watch()监听整个state watch( pinia.state, (state) => { localStorage.setItem('piniaState', JSON.stringify(state) }, {deep: true} )
-
-
-
Getter const store = useStore() store.getterProp
-
Getter完全等同于store的state的计算值。通过defineStore() 的 getters属性定义。 推荐使用➡️箭头函数,接收 state 作为第一个参数
-
访问其他的Getter 可以通过 this 访问到整个 store 实例, 但必须定义返回类型(在TypeScript中) export const useCounterStore = defineStore({ state: () => ({ count: 0 }), getters: { doubleCount(state) { return state.count * 2 }, doublePlusOne(): number { return this.doubleCount + 1 } } })
-
向Getter传递参数 可以从Getter返回一个函数,从而解决不能传递参数的问题 可以在getter 本身中缓存一些结果 解决 getter被调用后getter将不在被缓存的问题
-
访问其他store的getter 可以直接在Getter中使用 import { useOtherStore } from './other-store' export const useStore = defineStore('main', { state: () => ({ // ... }), getters: { otherGetter(state) { const otherStore = useOtherStore() return state.localData + otherStore.data }, }, })
-
使用setup() 时的用法 作为store的一个属性,可以直接访问任何getter和state
-
使用选项时API 可以通过在setup() 中使用 可以通过辅助函数mapState() 函数来映射getters
-
-
Action const store = useStore() const actionProp = store.actionProp
-
Action 相当于组件中method。 通过defineStore() 中的 actions 属性定义。 是定义业务逻辑的完美选择 action 可以 通过 this 访问整个 store 实例 action 可以时异步的 action 可以像函数或者通常意义上的方法一样被调用
-
访问其他store的action 直接引入store,然后在 action 中直接调用即可
-
使用选项式API的用法 使用setup() 不使用setup(), 可以使用辅助函数 mapActions() ,将 action 映射为对应组件中的方法
-
订阅action 可以通过 store.$onAction() 监听 action 和 它们的结果 传递给$onAction(callback, false)函数的回调函数 是在action本身之前执行 callback: () => { after(() => {}) onError((error) => {}) } after() ,表示在promise解决之后执行,即在action解决之后执行一个回调函数 onError(), 表示在action抛出错误或reject时执行一个回调函数 action 订阅器会被绑定到添加它们的组件上(如果store在组件的 setup()内)。则组件卸载时,它们将会被自动删除。 若需要保留,则将第二个参数设置为true, 以便将其从当前组件中分离。
-
-
插件
-
插件是一个函数,可以选择性的返回要添加到store 的属性。 接收一个参数,即context context { pinia // 用creatPinia()创建的 pinia app // 用createApp()创建的当前应用 store // 插件想扩展的 store options // 定义传给 defineStore() 的 store 的 可选对象 } 注意: 1. 每个 store 都被 reactive 包装过,所以可以自动解包任何包含的Ref(ref( ) / computed() ...) 2. 插件中,state 变更和添加都是发生在 store 被激活之前, 因此不会触发任何订阅函数 然后使用pinia.use(myPiniaPlugin)
-
扩展Store 返回特定属性的对象 为 每个store 添加特定的属性 pinia.use( () => { hello: 'world' })
-
添加新的state, 需要同时在两个地方添加 1. 在 store 上添加自定义属性 2. 在 store.$state上添加自定义属性 添加新的外部属性 先用 markRaw()包装,在传递给pinia import { markRaw } from 'vue' impor { router } from './router' pinia.use(({ store }) => { store.router = markRaw(router) } )
-
直接在store上设置属性 pinia.use(({ store }) => { store.hello = 'world' })
-
在devtools中调试, 为追踪到添加的自定义属性,在dev开发模式下需要添加到 store._customProperties中 pinia.use(({ store }) => { store.hello = 'world' if (process.env.NODE_ENV === 'development') { store._customProperties.add('hello') } })
-
在插件中调用 $subscribe 可以在插件中调用store.$subscrbe , store.$onAction 添加新的选项, 在定义store 时, 可以创建新的选项,以便在插件中使用它们
-
-
组件外的Store
-
在用 app.use(pinia) 安装 pinia 插件后,对 useStore() 的任何调用都会正常执行:
-
-
-
Pinia 系统学习
最新推荐文章于 2024-08-15 16:29:25 发布