信息发布→ 登录 注册 退出

Pinia简单使用以及数据持久化详解

发布时间:2026-01-11

点击量:
目录
  • 基本介绍
  • 基本使用与state
  • actions的使用
  • getters的使用
  • storeToRefs的使用
  • pinia模块化
  • pinia数据持久化
    • 用法
    • 常见疑问
    • 进阶用法
  • 总结

    基本介绍

    Pinia 是 Vue.js 的轻量级状态管理库

    官方网站:pinia.vuejs.org/

    • pinia和vuex4一样,也是vue官方的状态管理工具(作者是 Vue 核心团队成员)
    • pinia相比vuex4,对于vue3的兼容性更好
    • pinia相比vuex4,具备完善的类型推荐
    • pinia同样支持vue开发者工具,最新的开发者工具对vuex4支持不好

    pinia核心概念

    • state: 状态
    • actions: 修改状态(包括同步和异步,pinia中没有mutations)
    • getters: 计算属性

    基本使用与state

    目标:掌握pinia的使用步骤

    (1)安装

    yarn add pinia
    # or
    npm i pinia

    (2)在main.js中挂载pinia

    import { createApp } from 'vue'
    import App from './App.vue'
    
    import { createPinia } from 'pinia'
    const pinia = createPinia()
    
    createApp(App).use(pinia).mount('#app')

    (3)新建文件store/counter.js

    import { defineStore } from 'pinia'
    // 创建store,命名规则: useXxxxStore
    // 参数1:store的唯一表示
    // 参数2:对象,可以提供state actions getters
    const useCounterStore = defineStore('counter', {
      state: () => {
        return {
          count: 0,
        }
      },
      getters: {
       
      },
      actions: {
        
      },
    })
    
    export default useCounterStore

    (4) 在组件中使用

    <script setup>
    import useCounterStore from './store/counter'
    
    const counter = useCounterStore()
    </script>
    
    <template>
      <h1>根组件---{{ counter.count }}</h1>
    </template>
    
    <style></style>

    actions的使用

    目标:掌握pinia中actions的使用

    在pinia中没有mutations,只有actions,不管是同步还是异步的代码,都可以在actions中完成。

    (1)在actions中提供方法并且修改数据

    import { defineStore } from 'pinia'
    // 1. 创建store
    // 参数1:store的唯一表示
    // 参数2:对象,可以提供state actions getters
    const useCounterStore = defineStore('counter', {
      state: () => {
        return {
          count: 0,
        }
      },
      actions: {
        increment() {
          this.count++
        },
        incrementAsync() {
          setTimeout(() => {
            this.count++
          }, 1000)
        },
      },
    })
    
    export default useCounterStore

    (2)在组件中使用

    <script setup>
    import useCounterStore from './store/counter'
    
    const counter = useCounterStore()
    </script>
    
    <template>
      <h1>根组件---{{ counter.count }}</h1>
      <button @click="counter.increment">加1</button>
      <button @click="counter.incrementAsync">异步加1</button>
    </template>

    getters的使用

    pinia中的getters和vuex中的基本是一样的,也带有缓存的功能

    (1)在getters中提供计算属性

    import { defineStore } from 'pinia'
    // 1. 创建store
    // 参数1:store的唯一表示
    // 参数2:对象,可以提供state actions getters
    const useCounterStore = defineStore('counter', {
      state: () => {
        return {
          count: 0,
        }
      },
      getters: {
        double() {
          return this.count * 2
        },
      },
      actions: {
        increment() {
          this.count++
        },
        incrementAsync() {
          setTimeout(() => {
            this.count++
          }, 1000)
        },
      },
    })
    
    export default useCounterStore

    (2)在组件中使用

      <h1>根组件---{{ counter.count }}</h1>
      <h3>{{ counter.double }}</h3>

    storeToRefs的使用

    目标:掌握storeToRefs的使用

    如果直接从pinia中解构数据,会丢失响应式, 使用storeToRefs可以保证解构出来的数据也是响应式的

    <script setup>
    import { storeToRefs } from 'pinia'
    import useCounterStore from './store/counter'
    
    const counter = useCounterStore()
    // 如果直接从pinia中解构数据,会丢失响应式
    const { count, double } = counter
    
    // 使用storeToRefs可以保证解构出来的数据也是响应式的
    const { count, double } = storeToRefs(counter)
    </script>

    pinia模块化

    在复杂项目中,不可能把多个模块的数据都定义到一个store中,一般来说会一个模块对应一个store,最后通过一个根store进行整合

    (1)新建store/user.js文件

    import { defineStore } from 'pinia'
    
    const useUserStore = defineStore('user', {
      state: () => {
        return {
          name: 'zs',
          age: 100,
        }
      },
    })
    
    export default useUserStore

    (2)新建store/index.js

    import useUserStore from './user'
    import useCounterStore from './counter'
    
    // 统一导出useStore方法
    export default function useStore() {
      return {
        user: useUserStore(),
        counter: useCounterStore(),
      }
    }

    (3)在组件中使用

    <script setup>
    import { storeToRefs } from 'pinia'
    import useStore from './store'
    const { counter } = useStore()
    
    // 使用storeToRefs可以保证解构出来的数据也是响应式的
    const { count, double } = storeToRefs(counter)
    </script>

    pinia数据持久化

    目标: 通过 Pinia 插件快速实现持久化存储。

    插件文档:点击查看

    用法

    安装

    yarn add pinia-plugin-persistedstate
    or
    npm i  pinia-plugin-persistedstate

    使用插件 在main.ts中注册

    import { createApp } from "vue";
    import App from "./App.vue";
    import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
    
    const pinia = createPinia();
    pinia.use(piniaPluginPersistedstate);
    createApp(App).use(pinia);

    模块开启持久化

    const useHomeStore = defineStore("home",{
      // 开启数据持久化
      persist: true
      // ...省略
    });

    常见疑问

    • 模块做了持久化后,以后数据会不会变,怎么办?
      • 先读取本地的数据,如果新的请求获取到新数据,会自动把新数据覆盖掉旧的数据。
      • 无需额外处理,插件会自己更新到最新数据。

    进阶用法

    需求:不想所有数据都持久化处理,能不能按需持久化所需数据,怎么办?

    • 可以用配置式写法,按需缓存某些模块的数据。
    import { defineStore } from 'pinia'
    
    export const useStore = defineStore('main', s{
      state: () => {
        return {
          someState: 'hello pinia',
          nested: {
            data: 'nested pinia',
          },
        }
      },
      // 所有数据持久化
      // persist: true,
      // 持久化存储插件其他配置
      persist: {
        // 修改存储中使用的键名称,默认为当前 Store的 id
        key: 'storekey',
        // 修改为 sessionStorage,默认为 localStorage
        storage: window.sessionStorage,
        // 部分持久化状态的点符号路径数组,[]意味着没有状态被持久化(默认为undefined,持久化整个状态)
        paths: ['nested.data'],
      },
    })

    总结:相比于vuex,pinia对于typescript的支持性更好,友好的devTools支持,pinia只有1kb,简化了很多方法的写法。

    总结

    在线客服
    服务热线

    服务热线

    4008888355

    微信咨询
    二维码
    返回顶部
    ×二维码

    截屏,微信识别二维码

    打开微信

    微信号已复制,请打开微信添加咨询详情!