Pinia(五)了解和使用plugin

Plugins

  1. plugin 是一个函数, 其接收一个 context 作为参数, 其返回值将会被添加到 store 上.

    • context 参数
      • pinia: createPinia() 返回的 Pinia 实例
      • app: createApp() 返回的 app
      • store: 被插件作用的 store
      • options: 定义 defineStore 时传入第三个参数
    • 返回值
      • 返回对象, 其中的属性将被添加到 store. 或者返回 void
    • 📕只有 pinia 实例被传给 app 之后创建的 store 才会被 plugin 作用.
  2. plugin 的简单使用

    • 创建 src/store/plugin/test.ts

      • import { PiniaPluginContext } from 'pinia'
        
        export default function (context: PiniaPluginContext) {
          console.log('context.pinia', context.pinia);
          console.log('context.app', context.app);
          console.log('context.store', context.store);
          console.log('context.options', context.options);
          return {
            secret: 'don\'t tell anyone!'
          }
        }
        
    • main.js

      • import { createPinia } from 'pinia'
        import myPiniaPlugin from './store/plugin/test'
        
        const app = createApp(App);
        const pinia = createPinia();
        app.use(pinia);
        pinia.use(myPiniaPlugin);
        
    • 看下面的截图, 只有 usercounter 两个 store 被插件作用了, 而且每个 store 上都有 plugin 返回的参数.

    • 在这里插入图片描述

    • 在这里插入图片描述

    • 当然可以通过 store.[属性] 的方式直接使用

      • <h2>By Plugin: {{ user.secret }}</h2>
        
      • 在这里插入图片描述
    • 📕返回的参数每个 store 各自一份, 并不共享. 即如果你修改了 store Asecret, store Bsecret 不会被影响.

  3. store 添加参数

    • 可以直接通过 store.[属性] 的方式给 store 添加参数, 但是官网建议尽量使用返回值的方式来从而被开发者工具跟踪
      • 📕这种方式同样每个 store 都有自己的数据, 互不影响.

      • 📕这种方式其实就是给 store 添加新的 state

      • export default function (context: PiniaPluginContext) {
        
          context.store.hello = 'world';
          return {
            secret: 'don\'t tell anyone!'
          }
        } 
        
      • 这样的方式开发者工具并不会侦测到属性的添加, 只有在控制台打印 store 时才可以看到

      • 在这里插入图片描述

      • 如果一定要在开发者工具中看到这个属性, 请保证 开发环境 下使用 _customProperties. 因为生产环境下会被移除

        • context.store.hello = 'world';
          if (process.env.NODE_ENV === 'development') {
            context.store._customProperties.add('hello');
          }
          
        • 在这里插入图片描述
  4. store 添加响应式参数

    • 📕另外, 如果定义属性时使用响应式数据, 那么每个 store 都会有自己的属性;
    • 由于 store 本身是 reactive, 其会自动解包内部的 ref 或者 reactive, 因此在访问器内部响应式数据时不需要使用 .value
    • context.store.good = ref('bye');
      console.log('no unwrapping', context.store.good);
      
    • 在组件中使用
      • <h2>By Plugin Reactive: {{ user.good }}</h2>
        
      • function updateRefGood() {
          user.good = 'hahaha'
          console.log('after changing user good ', count.good)
        }
        
    • 在这里插入图片描述
  • 但是响应式数据定义在插件之外, 那么所有的 store 共享一个属性.
    • 同样的套路, 现在 plugin 中定义数据
    • const bad = ref('sad')
      export default function (context: PiniaPluginContext) {
      
        context.store.hello = 'world';
      
        // each store has its own good
        context.store.good = ref('bye');
        console.log('no unwrapping', context.store.good);
      
        // all store share the same bad
        context.store.bad = bad;
      
        return {
          secret: 'don\'t tell anyone!'
        }
      }
      
    • 在组件中
      • <h2>By Plugin nonReactive: {{ user.bad }}</h2>
        <button @click="updateRefBad">updateRefBad</button>
        
      • function updateRefBad() {
          user.bad = 'happy';
          console.log('after changing user bad ', count.bad)
        } 
        
      • 在这里插入图片描述
  1. store 添加新的 state
    • 如果想给 store 添加新的 state property 可以通过下面两种方式
      • 直接通过 store.[属性名]
      • 通过 store.$state 这样才能在开发者工具中使用, 并且在 SSR 过程中被序列化.
    • 下面看第二种
      • export default function({ store } : PiniaPluginContext) {
          if (!Object.prototype.hasOwnProperty(store.$state, 'hasError')) {
            const hasError = ref(false);
            store.$state.hasError = hasError;
          }
          store.hasError = toRef(store.$state, 'hasError');
        }
        
      • 1️⃣ 首先, 为了正确处理 SSR, 需要确保不覆盖任何已存在的值. 因此先判断是否存在 hasError
      • 2️⃣ 如果不存在, 那么使用 ref 定义. 这样每个 store 都会有自己独立的 hasError
      • 3️⃣ 其次, 如果已经存在 hasError, 我们需要将 hasErrorstate 转移到 store, 这样既可以通过 store.hasError 访问, 也可以通过 store.$state.hasError 访问.
    • 📕这种情况下, 最后不要在 return 时返回 hasError 了. 因为返回值会被展示在开发者工具中的 state 部分, 又定义又返回就会展示两次了.
    • 📕在 plugin 中的增加 state 或修改 state, 都不触发任何的订阅, 因为这时 store 并不活跃
  2. 添加外部属性
    • 如果要添加外部属性, 添加来自其他库的类的实例, 添加其他非响应式的数据, 我们应该使用 markRaw 包装一下再传递给 pinia.
    • context.store.language = markRaw({
        locale: 'zh-CN',
      });
      
  3. 调用 $onAction$subscribe
    • context.store.$subscribe((mutation, state) => {
        // ...
      });
      context.store.$onAction(() => {
        // ...
      });
      
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Pinia 是一个用于 Vue.js 的状态管理库,它提供了一种简单且可扩展的方式来管理应用程序的状态。Pinia-plugin-persistedstate 是一个 Pinia 插件,它可以帮助你将应用程序的状态持久化到本地存储中,以便在刷新页面或重新加载应用程序时保持状态的一致性。 使用 pinia-plugin-persistedstate 插件进行持久化的步骤如下: 1. 安装插件: 你可以使用 npm 或者 yarn 来安装插件: ``` npm install pinia-plugin-persistedstate ``` 或者 ``` yarn add pinia-plugin-persistedstate ``` 2. 导入插件并注册: 在你的应用程序的入口文件中,导入 `pinia-plugin-persistedstate` 并将其注册到 Pinia 实例中: ```javascript import { createApp } from 'vue' import { createPinia } from 'pinia' import { createPersistedState } from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(createPersistedState()) const app = createApp(App) app.use(pinia) app.mount('#app') ``` 3. 配置插件: 你可以通过传递选项对象来配置插件,例如指定要持久化的状态模块、存储键名等: ```javascript pinia.use(createPersistedState({ key: 'my-app-state', // 存储键名,默认为 'pinia-state' paths: ['counter'], // 要持久化的状态模块,默认为全部模块 storage: localStorage // 存储引擎,默认为 localStorage })) ``` 4. 使用持久化的状态: 在你的组件中,你可以像使用普通的 Pinia 状态一样使用持久化的状态: ```javascript import { useStore } from 'pinia' export default { setup() { const store = useStore() // 读取持久化的状态 console.log(store.counter) // 修改持久化的状态 store.counter++ } } ``` 这样,你就可以使用 pinia-plugin-persistedstate 插件来实现 Pinia 状态的持久化了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值