Vue3项目使用Pinia

本文旨在介绍在Vue3的项目中状态变量的管理,着重介绍 pinia ,这也是 Vue3 官方推荐的方式。

1. Pinia 介绍

Pinia的介绍

Pinia 起始于 2019 年 11 月左右的一次实验,其目的是设计一个拥有组合式 API 的 Vue 状态管理库。是Vuex的的简化。都是用于Vue的状态管理工具。

pinia官方文档: https://pinia.vuejs.org/zh/introduction.html

Pinia 与 vuex的简单对比
功能描述 Pinia Vuex 说明
Vue3中使用 官方推荐 完美兼容。 Vue2中更推荐使用vuex
TS的支持 完全支持 支持,但需要很多手动定义
模块化 天然支持 支持,需要叫复杂的配置后兼容
撸码过程 更少的流程,更直接的操作方法 更多的api,学习曲线陡峭 使用过Vuex,再使用pinia会十分容易上手
插件 够用 丰富
Store 已经默认模块化定义 需要手动进行拆分 Pinia 中 @stores/xx的每个 xx 即为一个模块
State const count = ref(0) State: { count: 0 } Pinia 使用选项式时与vuex基本相同。pinia使用组合式时像在.vue组件中声明 ref 变量一样。
$reset 选项式中已经默认定义了 $reset, setup中需要手动实现 需要手动实现 pinia中参考
Getter const doubleCount = computed(() => count.value * 2) getters: { doubleCount: (state) => state.count * 2, }, Pinia 使用选项式时与vuex基本相同
Aciton function increment() { count.value++ } actions: { increment() { this.count++ }, }, Pinia 使用选项式时与vuex基本相同
commit 触发 mutations 的语法
Dispath 触发 actions (异步)的语法

2. Pinia在Vue3项目的使用方法

  1. 安装,如果使用vite配置模板会在代码初始化时选择是否安装,也可以如下指令安装。
yarn add pinia
# 或者使用 npm
npm install pinia
  1. 全局引用 pinia, 在入口文件 main.ts 中操作

    import { createPinia } from 'pinia'
    
    const app = createApp(App)
    
    app.use(createPinia()) // 引入pinia的实例
    
    app.mount('#app')
    
  1. 定义 state。以counter 为例,在 src/stores 目录下创建 counter.ts文件。

    import { ref, computed } from 'vue'
    import { defineStore } from 'pinia'
    export const useCounterStore = defineStore('counter', () => {
      const count = ref(0)
      const doubleCount = computed(() => count.value * 2)
      function increment() {
        count.value++
      }
      function mixins(step:number) {
        count.value -= step
      }
      return { count, doubleCount, increment, mixins } // 只有return 出去的才能被外部调用
    })
    
    

    也可以使用 选项式 api定义 state.具体参考 https://pinia.vuejs.org/zh/core-concepts/#option-stores

  2. 调用 state。比如在 app.vue 组件中调用, 默认配置了 @stores的路径别名。

    import {useCounterStore} from '@stores/counter'
    const store = useCounterStore()
    onMounted(() => {
     console.log(store.count) // 获取 count的值
     store.increment() // 更新count
     store.mixins(3) // 更新count
      store.count = 10 // 甚至支持这么修改状态数据
    })
    
  1. 解构state。使用 store.xxx 访问比较麻烦,可以解构 store,还需保持响应性需要使用storeToRefs参考如下代码

    import {storeToRefs} from 'pinia'
    import {useCounterStore} from '@stores/counter'
    const store = useCounterStore()
    const {count, doubleCount} = storeToRefs(store)
    const {increment, mixinx} = store // 函数不能响应式解构,也不无需响应式解构
    onMounted(() => {
      console.log(count, doubleCount)
      increment() 
      mixins(3)
    })
    
  2. 模块化描述

    如上面 counter 的示例, 每个 counter就是一个独立的模块。如果需要其他模块比如menus,只需要在 @stores/menus.ts按照 counter的模式进行声明和调用即可,这也就是 pinia 天然就已经进行模块化封装好,我们只需按照规则进行声明和调用即可。

3. Pinia数据持久化

pinia的state状态数据和 vuex 一样,都是存在内存中的,刷新页面或关闭页面再次打开state都会丢失。有些状态值需要长久保存,比如 token等。这里介绍使用 pinia-plugin-persistedstatepinia的官方插件实现持久化。类似vuex-persistedstatevuex的数据持久化插件。

pinia-plugin-persistedstate官方文档:https://prazdevs.github.io/pinia-plugin-persistedstate/zh/

pinia-plugin-persistedstate的数据持久化也只是把状态数据存储到localStorage(默认) 或者 sessionStorage中。缓存有大小限制(5M左右),所以并不是所有数据都适合持久化操作。

具体操作如下:

  1. 安装插件

    yarn add pinia-plugin-persistedstate
    # or npm
    npm i pinia-plugin-persistedstate
    # or pnpm
    pnpm add pinia-plugin-persistedstate
    
  1. 将插件添加到 pinia 的实例中。main.ts文件

    import { createPinia } from 'pinia'
    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
    
    const pinia = createPinia()
    pinia.use(piniaPluginPersistedstate)
    
  1. 用法

    import { ref, computed } from 'vue'
    import { defineStore } from 'pinia'
    export const useCounterStore = defineStore(
      'counter',
      () => {
        const count = ref(0)
        const doubleCount = computed(() => count.value * 2)
        function increment() {
          count.value++
        }
        function mixins(step:number) {
          count.value -= step
        }
         return { count, doubleCount, increment, mixins }
     },
      {
        // persist: true, // 数据持久化配置, 或者传入一个对象添加更多配置
        persist: {
          key: 'my-counter', // 持久化的数据key
          storage: localStorage, // 或者sessionStorage
        }
      }
    )
    

    用来持久化的数据不能是异步的,而且必须能够进行序列化的与HTML缓存兼容一致的数据格式【字符串】。

  2. 高级使用方式。在 main.ts全局配置。

    // 支持 storage, serializer, debug 三项配置
    pinia.use(createPersistedState({
      storage: sessionStorage,
      serializer: {
        deserialize: parse,
        serialize: stringify
      },
      debug: true
    }))
    

    实现以上配置后,在单独的模块中不再需要单独进行配置。

    persist: {
      key: 'my-counter', // 持久化的数据key
    }
    // 或者
    persist: true
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容