多维数组、Vuex 和突变
Posted
技术标签:
【中文标题】多维数组、Vuex 和突变【英文标题】:Multidimensional Arrays, Vuex & Mutations 【发布时间】:2019-03-15 18:39:13 【问题描述】:我正在尝试在 Vuex 中存储的多维数组中添加和删除项目。
数组是一组类别,并且每个类别又有一个子类别(无穷大,而不是简单的二维数组)。
示例数据集是这样的:
[
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 商店内?
我通常使用 Vue.Set() 操作 Vuex Store 中的简单数组以获得反应性。但是,因为我不确定被操作的嵌套数组有多深 - 我根本无法弄清楚。
这是一个我认为可以使用递归添加子类别元素的示例:
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)
【问题讨论】:
【参考方案1】:首先要了解的是,vuex
或任何其他基于flux
架构的状态管理库并非旨在处理嵌套对象图,更不用说您提到的任意/无限嵌套对象了。更糟糕的是,即使是浅状态对象,vuex
在 define the shape of the state (all desired fields) upfront 时效果最好。
恕我直言,您可以采取两种可能的方法
1。规范化您的数据
这是 vue.js 团队成员 [here][2] 推荐的一种方法。如果你真的想在规范化后保留关于层次结构的信息,你可以使用flat 结合一个转换函数将你的嵌套对象通过name
扁平化为如下所示:
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()
。
2。在修改时创建一个全新的状态对象
这是vuex
's documentation中提到的第二种方法:
向对象添加新属性时,您应该:
使用
Vue.set(obj, 'newProp', 123)
,或用一个新的对象替换那个对象
...
您可以使用另一个库轻松实现此目的:object-path-immutable。例如,假设您想在languages
下添加新类别,您可以像这样创建一个突变:
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.data
所做的更改。如果您不想对数据进行规范化/非规范化,这种方法是可取的。
【讨论】:
非常感谢您的回答,这正是我所需要的。 @muffinlab 很高兴它有帮助。 :)以上是关于多维数组、Vuex 和突变的主要内容,如果未能解决你的问题,请参考以下文章