如何对 Vuex 持久化状态进行更改?

问题描述 投票:0回答:1

我们在我们的应用程序中使用持久化的本地存储状态。

向商店模块添加新字段或值时,它们不会应用于现有用户的状态。它仅在清除存储时有效。

应该如何解决这个问题?

我想到的一个可能的解决方案如下:

  1. 创建原型/辅助对象,用于状态初始化
  2. 在应用程序加载时,获取用户的状态对象并将键/值对与该原始对象进行比较
  3. 查找丢失的数据并将这些添加到用户的状态对象

这是一个可行的选择还是有更好的方法来处理这个问题?

javascript local-storage vuex web-frontend vuex-persist
1个回答
0
投票

在不深入了解实现细节的情况下,您应该像这样将 localStorage 状态与现有的 vuex 状态合并:

export const mutations: MutationTree<YourState> = {
   MERGE_USER_STATE(state, userState: Partial<YourState>) {
      state = {...state, ...userState};
   }
}

这将使用缓存在用户 localStorage 中的先前状态扩展您的现有状态。现有密钥将被覆盖,同时保留新密钥。

虽然这有一些缺点:

  • 嵌套对象总是被覆盖。所以对象内的新键被覆盖
  • 你失去了对每个用户状态中存储的内容的跟踪,这可能会变得非常复杂调试。

更好的方法是使用版本控制机制并自己处理转换。这样您就了解了存储在用户本地存储中的模式,并可以将该模式转换为您想要的任何内容。

给定一个用户有一个本地存储

state
项目包含:

{ 
  version: 1, 
  data: {
     favoriteAnimals: ["Dog", "Cat"]
  }
}

并给出一个 vuex 商店,允许用户添加/编辑他们最喜欢的动物:

export const state = () => {
  version: 1,
  favoriteAnimals: []
}

export const mutations = {
   ADD_ANIMAL(state, animal: string){
     state.favoriteAnimals.push(animal);
     localStorage.setItem('state', JSON.stringify({
      version: state.version,
      data: state
   })
)

   },
   // more mutations to remove and whatnot
}

export const actions = {
   add(context, animal: string){
      commit("ADD_ANIMAL", animal);
   },

   load(context, userState: string){ // userState = localStorage state
      const {version, data} = JSON.parse(state);
      // for now we don't care about data. we assume data is an array of strings
     data.forEach(animal => commit("ADD_ANIMAL", animal);
   }
}

现在您的团队中的几周决定将最喜欢的动物列表从字符串列表更改为对象列表,如下所示:

[ { animal: "Dog", ranking: 5 } ]

很明显,当用户访问他的旧本地存储时,您的应用程序将崩溃,因为现在类型不兼容。

你现在可以像这样编辑你的

load
动作:

load(context, userState: string){ // userState = localStorage state
     const {version, data} = JSON.parse(state);
     if (version === 1){ // old user detected.
        data.forEach(animal => {
            commit("ADD_ANIMAL", { name: animal, ranking: 0 });
        });
        return;
     }
     
     // default action when the version is up to date
     data.forEach(animal => commit("ADD_ANIMAL", animal);
}

在一定规模上,这将成长为一个越来越大的功能,尽管我认为它很好,因为它很容易扩展。您始终可以添加分析并跟踪您的用户实际使用的版本。这还有一个额外的好处,即每个用户的状态都会在他们打开应用程序时自动更新,因为 vuex 会在提交到它的内部状态后相应地更新状态。

© www.soinside.com 2019 - 2024. All rights reserved.