使用pinia-plugin-persistedstate实现数据存储

一、安装依赖

需要安装 Pinia 及其持久化插件。你可以使用 npm 或 yarn 进行安装:


# 使用 npm
 
npm install pinia pinia-plugin-persistedstate
 
# 或使用 yarn
 
yarn add pinia pinia-plugin-persistedstate
 

二、全局配置(main.js / main.ts

在项目的入口文件中,初始化 Pinia 并注册持久化插件。以下是基本的配置步骤:

1. 基础配置


// main.js 或 main.ts
 
import { createApp } from 'vue';
 
import { createPinia } from 'pinia';
 
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
 
import App from './App.vue';
 
// 创建 Pinia 实例
 
const pinia = createPinia();
 
// 注册持久化插件(全局启用,默认配置)
 
pinia.use(piniaPluginPersistedstate);
 
// 挂载 Vue 应用
 
const app = createApp(App);
 
app.use(pinia);
 
app.mount('#app');
 

2. 自定义插件配置(可选)

如果需要自定义持久化行为,可以在注册插件时传入配置对象。例如:


// main.js 或 main.ts
 
import { createApp } from 'vue';
 
import { createPinia } from 'pinia';
 
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate';
 
import App from './App.vue';
 
// 创建 Pinia 实例
 
const pinia = createPinia();
 
// 自定义持久化插件配置
 
pinia.use(piniaPluginPersistedstate({
 
  storage: sessionStorage, // 使用 sessionStorage 替代默认的 localStorage
 
  key: (store) => `app_${store.$id}`, // 使用 store 的 id 作为存储键的前缀
 
  paths: ['token', 'theme'], // 全局默认持久化字段(可覆盖单个 Store 的配置)
 
  debug: true, // 开启调试模式,控制台输出日志
 
  beforeHydrate: (context) => {
 
    console.log('数据恢复前触发');
 
    // 可以在这里添加自定义逻辑,例如修改即将加载的数据
 
  },
 
  afterHydrate: (context) => {
 
    console.log('数据恢复后触发');
 
    // 数据已经恢复完成,可以在这里执行其他操作
 
  }
 
}));
 
// 挂载 Vue 应用
 
const app = createApp(App);
 
app.use(pinia);
 
app.mount('#app');
 

配置参数说明:

  • storage: 指定使用的存储机制,默认为 localStorage。可以设置为 sessionStorage 或其他自定义存储。

  • key: 定义存储键的前缀。默认为。通过函数可以根据不同 store 动态生成键名。

  • paths: 指定默认需要持久化的字段路径。如果不设置,默认持久化所有可序列化的字段。

  • debug: 是否开启调试模式,开启后会在控制台输出相关日志,便于开发调试。

  • beforeHydrate 和 afterHydrate: 数据恢复前后的钩子函数,可以在其中执行一些自定义逻辑。

三、Store 定义(组合式 API)

Pinia 支持组合式 API,使得定义 store 更加简洁直观。下面展示如何在组合式 API 中配置持久化。

1. 基础配置(持久化全部字段)


// stores/user.js
 
import { defineStore } from 'pinia';
 
import { ref } from 'vue';
 
export const useUserStore = defineStore('user', () => {
 
  // 状态定义
 
  const token = ref('');        // 用户 token
 
  const userInfo = ref(null);   // 用户信息
 
  const theme = ref('light');   // 主题模式
 
  // 方法
 
  function login() {
 
    token.value = 'new-token-123';
 
    userInfo.value = { name: 'John', age: 25 };
 
  }
 
  // 返回状态和方法
 
  return { token, userInfo, theme, login };
 
}, {
 
  persist: true // 默认存储到 localStorage,键为 'user'
 
});
 

说明:

  • defineStore:定义一个名为 'user' 的 store。第二个参数为状态和方法的定义,第三个参数为 store 的配置对象。

  • persist: true:启用持久化功能,使用全局配置或默认设置。此时,整个 store 的所有可序列化字段将被持久化。

2. 高级配置(自定义存储策略)


// stores/user.js
 
export const useUserStore = defineStore('user', () => {
 
  const token = ref('');
 
  const userInfo = ref(null);
 
  const theme = ref('light');
 
  function login() {
 
    token.value = 'new-token-123';
 
    userInfo.value = { name: 'John', age: 25 };
 
  }
 
  return { token, userInfo, theme, login };
 
}, {
 
  persist: {
 
    storage: sessionStorage, // 使用 sessionStorage(默认是 localStorage)
 
    key: 'custom-user-key',  // 自定义存储键(默认是 store.)
 
    paths: ['token', 'theme'], // 仅持久化 token 和 theme 字段
 
    serializer: {            // 自定义序列化与反序列化(处理非 JSON 数据)
 
      serialize: (value) => JSON.stringify(value),
 
      deserialize: (value) => JSON.parse(value)
 
    }
 
  }
 
});
 

高级配置说明:

  • storage:指定持久化存储的位置,可以是 localStoragesessionStorage,甚至是自定义的存储机制。

  • key:自定义存储键名,确保唯一性以避免覆盖。这里设置为 'custom-user-key'

  • paths:指定需要持久化的字段路径。仅 token 和 theme 会被持久化,userInfo 不会被保存。

  • serializer:自定义序列化和反序列化方法。默认情况下,插件使用 JSON.stringify 和 JSON.parse。对于复杂的数据类型(如 DateMap),可以通过自定义序列化器来处理。

四、Store 定义(选项式 API)

除了组合式 API,Pinia 也支持选项式 API,以下是选项式 API 的配置示例。

1. 基础配置(持久化全部字段)


// stores/user.js
 
import { defineStore } from 'pinia';
 
export const useUserStore = defineStore('user', {
 
  state: () => ({
 
    token: '',        // 用户 token
 
    userInfo: null,   // 用户信息
 
    theme: 'light'    // 主题模式
 
  }),
 
  actions: {
 
    login() {
 
      this.token = 'new-token-123';
 
      this.userInfo = { name: 'John', age: 25 };
 
    }
 
  },
 
  persist: true // 默认存储到 localStorage,键为 'user'
 
});
 

说明:

  • state:定义 store 的状态。

  • actions:定义 store 的方法。

  • persist: true:启用基础持久化功能。

2. 高级配置(自定义存储策略)


// stores/user.js
 
export const useUserStore = defineStore('user', {
 
  state: () => ({
 
    token: '',
 
    userInfo: null,
 
    theme: 'light'
 
  }),
 
  actions: {
 
    login() {
 
      this.token = 'new-token-123';
 
      this.userInfo = { name: 'John', age: 25 };
 
    }
 
  },
 
  persist: {
 
    storage: sessionStorage, // 使用 sessionStorage(默认是 localStorage)
 
    key: 'custom-user-key',  // 自定义存储键(默认是 store.)
 
    paths: ['token', 'theme'], // 仅持久化 token 和 theme 字段
 
    serializer: {            // 自定义序列化与反序列化(处理非 JSON 数据)
 
      serialize: (value) => JSON.stringify(value),
 
      deserialize: (value) => JSON.parse(value)
 
    }
 
  }
 
});
 

说明:

与组合式 API 类似,选项式 API 也支持 persist 配置,用于自定义持久化行为。以上配置实现了仅持久化 token 和 theme,并使用自定义的存储键 'custom-user-key'

五、组件中使用(组合式 API)

在组件中,可以使用组合式 API 引入并使用 store,同时提供清除本地存储的方法。以下是一个基于组合式 API 的示例组件。

User.vue(组合式 API)


<template>
 
  <div>
 
    <p>Token: {{ userStore.token }}</p>
 
    <p>主题模式: {{ userStore.theme }}</p>
 
    <button @click="userStore.login">登录</button>
 
    <button @click="clearStorage">清除本地存储</button>
 
  </div>
 
</template>
 
<script setup>
 
import { useUserStore } from '@/stores/user';
 
// 引入 Store
 
const userStore = useUserStore();
 
// 清除本地存储的方法
 
const clearStorage = () => {
 
  localStorage.removeItem('user'); // 根据 persist.key 自定义键名,此处为默认值 'user'
 
};
 
</script>
 

说明:

  • 使用 setup 语法糖引入 store。

  • userStore.token 和 userStore.theme 直接绑定到模板中。

  • clearStorage 方法用于手动清除本地存储中的 store 数据。根据 persist.key 的设置,可能需要调整键名。例如,如果使用了自定义键名 'custom-user-key',则应相应地修改 localStorage.removeItem 的参数。

六、组件中使用(选项式 API)

对于习惯选项式 API 的,也可以在组件中使用 store。以下是一个基于选项式 API 的示例组件。

User.vue(选项式 API)


<template>
 
  <div>
 
    <p>Token: {{ userStore.token }}</p>
 
    <p>主题模式: {{ userStore.theme }}</p>
 
    <button @click="userStore.login">登录</button>
 
    <button @click="clearStorage">清除本地存储</button>
 
  </div>
 
</template>
 
<script>
 
import { useUserStore } from '@/stores/user';
 
import { defineComponent } from 'vue';
 
export default defineComponent({
 
  setup() {
 
    const userStore = useUserStore();
 
    return { userStore };
 
  },
 
  methods: {
 
    clearStorage() {
 
      localStorage.removeItem('user'); // 根据 persist.key 自定义键名,此处为默认值 'user'
 
    }
 
  }
 
});
 
</script>
 

说明:

  • 使用 setup 函数引入 store,并通过返回对象将其暴露给模板。

  • clearStorage 方法定义在 methods 中,同样根据 persist.key 设置相应的存储键名。

  • 如果使用了自定义键名,如 'custom-user-key',需将 'user' 替换为对应的键名。例如:localStorage.removeItem('custom-user-key')

七、高级功能

pinia-plugin-persistedstate 提供了更多高级功能,以满足复杂的应用场景需求。以下是一些高级功能的详细说明和使用示例。

1. 选择性持久化字段(pick / omit

有时我们只需要持久化 store 中的部分字段,而不是全部。插件提供了 pick 和 omit 选项来实现这一点。这两个选项互斥,即使用其中一个时另一个将被忽略。

使用 pick(仅持久化指定字段)

// stores/user.js(组合式 API)
 
export const useUserStore = defineStore('user', () => {
 
  const token = ref('');
 
  const userInfo = ref(null);
 
  const theme = ref('light');
 
  function login() { /* ... */ }
 
  return { token, userInfo, theme, login };
 
}, {
 
  persist: {
 
    pick: ['token', 'theme'] // 仅持久化 token 和 theme,忽略 userInfo
 
    // omit: ['userInfo'] // 如果使用 omit,效果相同,但两者不能同时使用
 
    // key: 'custom-user-key', // 可选,自定义存储键名
 
    // storage: sessionStorage, // 可选,自定义存储位置
 
    // paths: [] // 如果使用 pick/omit,paths 将被忽略或覆盖
 
    // ...其他配置项
 
  }
 
});
 

示例解释:

  • pick: ['token', 'theme']:表示只持久化 token 和 theme,其他字段如 userInfo 不会被持久化。这在敏感信息不需要持久化时非常有用。

  • omit:如果你更倾向于指定哪些字段不持久化,可以使用 omit。例如,omit: ['userInfo'] 达到的效果与 pick: ['token', 'theme'] 相同。注意两者不能同时使用。

  • 优先级:当同时指定 pick/omit 和 paths 时,pick/omit 将覆盖 paths。这是因为 pick/omit 更加明确地表达了意图。

  • 存储键名与位置:可以结合使用自定义的 key 和 storage,以灵活控制数据的存储位置和命名。例如,将敏感数据存储到 sessionStorage,并使用不同的键名以区分不同类型的数据。

  • 嵌套路径:如果需要更细粒度地选择字段路径,可以继续使用 paths。不过通常在简单的场景中,pick/omit 已经足够使用。例如,如果有一个嵌套的对象结构,可以使用类似 ['profile.name'] 的路径来仅持久化特定的嵌套属性。但在本例中,由于没有嵌套结构,所以未使用 paths。如果有嵌套需求,可以在 pick/omit 同时使用 paths,具体取决于实际需求和插件的处理逻辑。一般来说,为了避免冲突,建议在使用时只选择一种方式来指定要持久化的字段。如果确实需要同时使用,应该仔细测试以确保它们按预期工作。此外,插件文档通常会有详细的优先级和使用说明,建议参考官方文档以获取最新和最准确的信息。在实际项目中,根据团队的习惯和项目的复杂度选择合适的字段选择方式。对于简单项目,可能只需要基础的持久化配置;而对于复杂的应用,可能需要更精细地控制哪些数据被持久化以及如何存储这些数据。通过合理配置 pinia-plugin-persistedstate,可以有效地管理应用的状态持久化需求,提升用户体验和应用的稳定性。

### Pinia 插件功能对比 #### 功能特性 pinia-plugin-persistedstatepinia-plugin-persist 都用于持久化存储 Pinia 状态,但在实现方式和具体功能上存在差异。 对于 `pinia-plugin-persistedstate` 而言,该插件提供了更简洁的 API 设计以及更好的性能优化。开发者可以通过简单的配置选项轻松启用状态持久化,并支持多种存储介质的选择,如 localStorage 或 sessionStorage[^1]。 而 `pinia-plugin-persist` 则提供了一种更为灵活的状态保存机制,允许用户自定义序列化逻辑、过滤要保存的状态字段等功能。这使得在复杂应用场景下具有更高的可定制性和适应性。 #### 使用方法 ##### 安装依赖 无论是哪个插件,在使用前都需要先安装对应的 npm 包: ```bash npm install pinia-plugin-persistedstate # or npm install pinia-plugin-persist ``` ##### 基本用法示例 ###### 使用 `pinia-plugin-persistedstate` 引入并注册插件后,只需指定 store 实例即可自动完成状态持久化操作: ```javascript import { createPinia } from 'pinia' import persistedState from 'pinia-plugin-persistedstate' const pinia = createPinia() pinia.use(persistedState) // 创建 Store 并开启持久化 export const useMainStore = defineStore('main', { state: () => ({ count: 0, }), persist: true, // 开启持久化 }) ``` ###### 使用 `pinia-plugin-persist` 相比之下,`pinia-plugin-persist` 提供了更多细粒度控制的能力,比如可以针对不同类型的属性设置不同的持久化策略: ```javascript import { createPinia } from 'pinia'; import piniaPersist from "pinia-plugin-persist"; const pinia = createPinia(); pinia.use(piniaPersist); // 创建 Store 可以为特定属性设定持久化规则 export const useUserStore = defineStore({ id: 'user', state: () => ({ name: '', age: null, }), plugins: [ piniaPersist.plugin({ key: 'user-store', paths: ['name'], // 只有 name 属性会被持久化 }) ] }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值