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

How to create a persistant state for Pinia + Quasar?

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

我知道两个选项:

  1. 使用插件。 Vuex 有一个 vuex-persistedstate plugin for this, and Pinia has a similar plugin 但它仍在开发中。

  2. 使用本地存储。幸运的是,Quasar 有一个 LocalStorage plugin ,在这里使用它会很好。但我不确定如何将它与 Pinia 集成,因此 post.

我找到了一个不错的tutorial doing something similar with 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;
    },
  },
});

很遗憾,它不起作用。

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

关于如何使这项工作有任何想法吗?

我实际上使用“vanilla localStorage”并且没有遇到任何问题。 对于简单的任务,我不是太多库的忠实拥护者(尽管不将它们用于复杂的任务)。 不管怎样,我也是 VueUse 的粉丝。这个功能我没用过,但我可以imagine.it让事情变得更简单。

香草本地存储

设置到本地存储

localStorage.setItem("myStorageKey", "My persisted values");

从本地存储获取

localStorage.getItem("myStorageKey");

状态突变

除此之外,我没有尝试将localStoreage设置为直接进入状态。这对我来说似乎是一个危险信号,因为你通常不应该直接改变状态。但在这种情况下我不确定。我通常会预先填充硬编码数据(或只是空的)的状态,然后我会编写一个操作,将数据设置到状态中。

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

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

setUser动作中,调用LocalStorage.set()将用户数据保存到Local Storage。

由于user是对象,克隆对象而不是直接赋值,这样store就不会不必要地保留对外部对象的引用。如果userData有嵌套属性,可以使用Quasar的extend到deep-copy对象:

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
    },
  }
})

demo

quasar-v2-ssr-pinia repository created before Pinia has official Quasar support. I tried to add pinia-plugin-persist and pinia-plugin-persistedstate in this PR,但这些 Pinia 插件无法与 Quasar SSR 一起使用,因此 Toby 推出了一个使用 Quasar 的 Cookie、SessionStorage 和 LocalStorage 采用者的持久状态示例。

好消息:它正在运行,您可以为任何商店使用任何存储采用器。

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

我打算将 Toby 的代码发布到 NPM 进行安装,而不是从示例中复制。