如何为Pinia + Quasar创建持久状态?

9

我正在使用Pinia进行状态管理,希望页面刷新时保持状态。

我知道两种选择:

  1. 使用插件。Vuex有一个vuex-persistedstate插件可以实现这个功能,而Pinia也有类似的插件,但它仍在开发中。

  2. 使用本地存储。幸运的是,Quasar有一个LocalStorage插件,在这里使用它会很好。但是我不确定如何将其与Pinia集成,所以写下了这篇文章。

我找到了一篇不错的教程,介绍了如何使用Pinia + Vueuse实现类似的功能。

我尝试根据以下代码,使用Pinia + TypeScript + Quasar LocalStorage 插件来满足我的需求:

import { User } from 'firebase/auth';
import { defineStore } from 'pinia';
import { LocalStorage } from 'quasar';

type CreateMutable<T> = { -readonly [P in keyof T]: CreateMutable<T[P]> };

export const useUserStore = defineStore('user', {
  state: () => ({
    // user: {} as CreateMutable<User>, // This was my previous non-persistent state
    user: LocalStorage.set('user', {}) as unknown as CreateMutable<User>, // This is my attempt at using LocalStorage persistent state
  }),
  actions: {
    setUser(userData: User) {
      this.user = userData;
    },
    setPhotoURL(photoURLData: string | null) {
      this.user.photoURL = photoURLData;
    },
  },
});

很遗憾,它不起作用。

状态在页面刷新时不会保存。

有什么想法可以让它工作吗?

3个回答

7

要使用Quasar的LocalStorage.getItem()以本地存储数据初始化user状态,并将其默认为空对象:

export const useUserStore = defineStore('user', {
  state: () => ({
    user: (LocalStorage.getItem('user') || {}) as CreateMutable<User>,
  }),
  ⋮

setUser操作中,调用LocalStorage.set()将用户数据保存到本地存储中。
由于user是一个对象,应该克隆该对象而不是直接赋值,以便存储不必要地保留对外部对象的引用。如果userData具有嵌套属性,则可以使用Quasar的extend进行深度复制对象。
import { extend, LocalStorage } from 'quasar'

export const useUserStore = defineStore('user', {
  ⋮
  actions: {
    setUser(userData: User) {
      const copyOfData = { ...userData }
      // or...
      const copyOfData = extend(true /* deep */, {}, userData)

      LocalStorage.set('user', copyOfData)
      this.user = copyOfData
    },
  }
})

演示


2

在Pinia官方支持Quasar之前,已经创建了quasar-v2-ssr-pinia存储库。我尝试在此 PR中添加pinia-plugin-persistpinia-plugin-persistedstate,但这些Pinia插件无法与Quasar SSR一起使用,因此Toby推出了使用Quasar的Cookies、SessionStorage和LocalStorage适配器实现持久状态的示例。

好消息:它可以工作,并且您可以为任何存储使用任何适配器。

坏消息:只有整个存储区域可以持续存在,而没有部分存储持久性。我们可以创建单独的存储来持久化其所有内容,作为解决方法。

我计划将Toby的代码发布到NPM上进行安装,以替代从示例中复制的方式。


2
我实际上使用的是“纯粹的localStorage”,并且没有遇到任何问题。对于简单的任务,我不太喜欢使用太多库(尽管对于复杂的任务不使用它们)。无论如何,我也是VueUse的粉丝。我还没有使用过这个函数,但我可以想象它会让事情变得更加容易。
纯粹的localStorage 将数据存储到本地存储中: localStorage.setItem("myStorageKey", "My persisted values");
从本地存储中获取数据: localStorage.getItem("myStorageKey");
状态突变
除此之外,我没有尝试直接将localStoreage设置到状态中。这似乎是一个警告信号,因为通常不应该直接改变状态。但在这种情况下,我不确定。我通常会使用硬编码数据(或者只是空数据)预先填充状态,然后编写一个操作,将数据设置到状态中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接