如何在Vuex中实现状态规范化?

海德·卢卡斯(Helder Lucas)

我也在开发使用Vuex的应用程序,并且遇到了处理嵌套对象会很痛苦的情况,因此我试图尽可能地规范化(扁平化)状态,如下例所示:

users: {
    1234: { ... },
    46473: { name: 'Tom', topics: [345, 3456] }
},
userList: [46473, 1234]

我的问题是:当您的API响应如下所示时,实现上述目标的“最佳”方法什么

data: [
    {id: 'u_0001', name: 'John', coments: [{id: 'c_001', body: 'Lorem Ipsum'}, {...}],
    {id: 'u_0002', name: 'Jane', coments: [{id: 'c_002', body: 'Lorem Ipsum'}, {...}],
    {...}
] 

为了示例的缘故,假设它comments是的子模块users

选项1:

// action on the user module
export const users = ({ commit, state }, users) => {
    commit(SET_USERS, users)
    commit('comments/SET_COMMENTS', users)
}


// mutation on the user module
[types.SET_USERS] (state, users) {
     state.users = users.reduce((obj, user) => {
         obj[user.id] = {
             id: user.id, 
             name: user.name,
             comments: user.comments.map(comment => comment.id)
         } 
         return obj
     }, {})
    state.userIds = users.map(user => user.id)
},


// mutation on the comments module
[types.SET_COMMENTS] (state, users) {
    let allComments = []
    users.forEach(user =>  {
        let comments = user.comments.reduce((obj, comment) => {
            obj[comment.id] = comment
            return obj
        }, {})
        allComments.push(comments)
    })

   state.comments = ...allComments
},

IMO这个选项很好,因为您不必担心每次更改页面(SPA / Vue-Router)时都要重置状态,避免了由于某种原因id: u_001而不再存在的情况,因为每次更改突变时都会覆盖该状态,但是users array将都传递给这两个突变体感觉很奇怪

选项2:

// action on the user module
export const users = ({ commit, state }, users) => {
    // Here you would have to reset the state first (I think)
    // commit(RESET)

    users.forEach(user => {
        commit(SET_USER, user)
        commit('comments/SET_COMMENTS', user.comments)
    })
}


// mutation on the user module
[types.SET_USER] (state, user) {
    state.users[user.id] = {
        id: user.id, 
        name: user.name,
        comments: user.comments.map(comment => comment.id)
    }  
    state.userIds.push(user.id)
},


// mutation on the comments module
[types.SET_COMMENTS] (state, comments) {
    comments.forEach(comment => {
        Vue.set(state.comments, comment.id, comment)
    })
    state.commentsIds.push(...comments.map(comment => comment.id)
},

在这种情况下,需要重置状态,否则每次离开并重新租用该页面时,您都会得到重复/旧的值。Wich有点烦人,并且更倾向于错误或行为不一致。

结论你们如何应对这种情况和建议/最佳实践?因为我坚持这些事情,所以答案非常感谢。

另外,由于需求并不那么复杂,因此我尝试避免使用3r方库,例如Vue ORM,normalizr等。

谢谢,

PS:由于我只是在未经测试的情况下编写代码,所以代码可能会出现错误,请着眼大图。

Varit J Patel

好吧,为避免发生以下状态中的意外复杂性,在进行状态归一化时需要注意一些要点。

如官方Redux文档所述

  1. 每种类型的数据在状态中都有其自己的“表”。
  2. 每个“数据表”应将单个项目存储在一个对象中,其中项目的ID作为键,而项目本身作为值。
  3. 对单个项目的任何引用都应通过存储项目的ID来完成。
  4. ID数组应用于指示顺序。

现在,使用上面的示例,从数据中删除冗余。您可以将每个表用于每个信息,例如userscomments等等。

{
  'users': {
    byId : {
      "user1" : {
        username : "user1",
        name : "User 1",
      },
      "user2" : {
        username : "user2",
        name : "User 2",
      },
      ...
    },
    allIds : ["user1", "user2", ..]
  },
  'comments': {
    byId : {
      "comment1" : {
        id : "comment1",
        author : "user2",
        body: 'Lorem Ipsum'
      },
      "comment2" : {
        id : "comment2",
        author : "user3",
        body: 'Lorem Ipsum'
    },
    allIds : ["comment1", "comment2"]
  }
}

这样,我们可以确保连接更多的组件并负责查找和维护自己的数据集,而不是每个组件都具有较大的数据集并将数据传递给儿童组件。

更新的答案

由于已经按照组件对数据进行了标准化,因此只需执行一次操作就可以将父组件中的实体传递出去,并且作为标准化的一部分,可以获得以下好处。

  1. 更快的数据访问,不再需要遍历数组或嵌套对象。
  2. 组件之间的耦合松动。
  3. 每个组成部分在商店中都有其自己的位置,因此只有一个真理。

希望这可以帮助!

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Firebase中写入非规范化数据

来自分类Dev

如何在R中反规范化嵌套列表?

来自分类Dev

如何在R中反规范化嵌套列表?

来自分类Dev

如何在Cassandra中处理非规范化

来自分类Dev

如何在 Hybris 中规范化 URL

来自分类Dev

Pytorch中的规范化如何工作?

来自分类Dev

如何实现solr领域的规范化?专家请指教

来自分类Dev

scikit-learn 在 Java 中规范化实现?

来自分类Dev

如何对R中的数据进行规范化和非规范化?

来自分类Dev

如何在Pyspark中规范化并创建相似性矩阵?

来自分类Dev

如何在SymPy中规范化表达式列表?

来自分类Dev

非规范化数据如何在React Redux中引起问题?

来自分类Dev

如何在Pyspark中规范化并创建相似性矩阵?

来自分类Dev

在坚持规范化的同时如何在数据库中存储数组?

来自分类Dev

如何在MATLAB中绘制非规范化频谱图?

来自分类Dev

如何在 MongoDB 中规范化数据模型/JSON?

来自分类Dev

Rails中的规范化

来自分类Dev

如何在Firebase中正确规范化数据

来自分类Dev

如何在C ++中正确规范化浮点值?

来自分类Dev

如何在SQL规范化中联接这些表

来自分类Dev

如何在 MySQL 中加入非规范化表?

来自分类Dev

如何在 python 中实现状态空间树(这是一个二叉树)?

来自分类Dev

如何实现状态值功能?

来自分类Dev

如何规范化Apache猪中的地图元组?

来自分类Dev

如何规范化数据库中的数据?

来自分类Dev

如何规范化Python中的wave读取?

来自分类Dev

如何规范化配置单元中的列?

来自分类Dev

如何对 MySQL 中的数据进行非规范化?

来自分类Dev

Redux嵌套化约化器或规范化状态?

Related 相关文章

热门标签

归档