多维数组,Vuex&变异 [英] Multidimensional Arrays, Vuex & Mutations

查看:74
本文介绍了多维数组,Vuex&变异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试添加和删除Vuex中存储的多维数组中的项目.

I'm attempting to both add and remove items in a multidimensional array stored in Vuex.

数组是一组类别,每个类别都有一个子类别(无穷大,不仅仅是二维数组).

The array is a group of categories, and each category and have a sub-category (infinity, not simply a two dimensional array).

示例数据集如下:

[
   {
     id: 123,
     name: 'technology',
     parent_id: null,
     children: [
          id: 456,
          name: 'languages',
          parent_id: 123,
          children: [
             {
                id:789,
                name: 'javascript',
                parent_id: 456
             }, {
                id:987,
                name: 'php',
                parent_id: 456
             }
          ]
        }, {
          id: 333,
          name: 'frameworks', 
          parent_id 123,
          children: [
             {
                id:777,
                name: 'quasar',
                parent_id: 333
             }
          ]
        }
     ]
   }
]

....我的问题是,如何最好地在Vuex商店内部的此数组中添加和删除元素?

....my question is, how do I best add and remove elements to this array, which is inside of a Vuex Store?

我通常使用Vue.Set()在Vuex Store中操作简单数组以获取反应性.但是,由于我不确定要操纵的嵌套数组有多深-我根本无法弄清楚.

I normally manipulate simple arrays inside the Vuex Store using Vue.Set() to get reactivity. However, because I'm not sure how deep the nested array being manipulated is - I simply can't figure it out.

以下是我认为可以使用递归添加子类别元素的示例:

Here's an example of how I thought I could add a sub-category element using recursion:

export const append = (state, item) => {
  if (item.parent_uid !== null) {
    var categories = []
    state.data.filter(function f (o) {
      if (o.uid === item.parent_uid) {
        console.log('found it')
        o.push(item)
        return o
      }
      if (o.children) {
        return (o.children = o.children.filter(f)).length
      }
    })
  } else {
    state.data.push(item)
  }
}

推荐答案

首先要了解的是 vuex 或任何其他基于 flux 架构的状态管理库并不是用来处理嵌套对象图的,更不用说您提到的任意/无限嵌套对象了.更糟糕的是,即使使用浅状态对象,当您

The first thing to understand is that vuex, or any other state management library based on flux architecture, isn't designed to handle nested object graph, let alone arbitrary/infinity nested objects that you mentioned. To make the matter worse, even with shallow state object, vuex works best when you define the shape of the state (all desired fields) upfront.

恕我直言,您可以采用两种方法

IMHO, there are two possible approaches you can take

这是vue.js团队成员此处.

This is an approach recommended by vue.js team member here.

如果您真的想在标准化后保留有关层次结构的信息,则可以使用 flat 与转换功能结合使用,以通过 name 将嵌套对象展平为类似这样的内容:

If you really want to retain information about the hierarchical structure after normalization, you can use flat in conjunction with a transformation function to flatten your nested object by name to something like this:

const store = new Vuex.Store({
  ...
  state: {
    data: {
      'technology':                      { id: 123, name: 'technology', parent_id: null },
      'technology.languages':            { id: 456, name: 'languages', parent_id: 123 },
      'technology.languages.javascript': { id: 789, name: 'javascript', parent_id: 456 },
      'technology.languages.php':        { id: 987, name: 'php', parent_id: 456 },
      'technology.frameworks':           { id: 333, name: 'frameworks', parent_id: 123 },
      'technology.frameworks.quasar':    { id: 777, name: 'quasar', parent_id: 333 },
    }
  },
});

然后,您可以像往常一样在 state.data 中的每个项目上使用 Vue.set().

Then you can use Vue.set() on each item in state.data as usual.

这是 vuex 文档中提到的第二种方法:

This is the second approach mentioned in vuex's documentation:

向对象添加新属性时,您应该:

When adding new properties to an Object, you should either:

  • 使用 Vue.set(obj,'newProp',123)

用一个新的对象替换该对象

Replace that Object with a fresh one

...

您可以使用另一个库轻松实现此目标:对象路径不可修改.例如,假设您想在 languages 下添加新类别,则可以创建如下所示的变体:

You can easily achieve this with another library: object-path-immutable. For example, suppose you want to add new category under languages, you can create a mutation like this:

const store = new Vuex.Store({
  mutations: {
    addCategory(state, { name, id, parent_id }) {
      state.data = immutable.push(state.data, '0.children.0.children', { id, name, parent_id });
    },
  },
  ...
});

每次进行修改时,通过将 state.data 重新分配给新对象, vuex 反应性系统将正确地通知您对 state所做的更改.数据.如果您不想对数据进行规范化/非规范化,则可以使用这种方法.

By reassigning state.data to a new object each time a modification is made, vuex reactivity system will be properly informed of changes you made to state.data. This approach is desirable if you don't want to normalize/denormalize your data.

这篇关于多维数组,Vuex&变异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆