多维数组、Vuex 和突变
Multidimensional Arrays, Vuex & Mutations
我正在尝试在 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 Store 内部的数组添加和删除元素?
我通常使用 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)
}
}
首先要了解的是 vuex
或任何其他基于 flux
体系结构的状态管理库并非旨在处理嵌套对象图,更不用说 arbitrary/infinity您提到的嵌套对象。更糟糕的是,即使使用浅状态对象,vuex
在 define the shape of the state (all desired fields) upfront.
时效果最好
恕我直言,您可以采取两种可能的方法
1。标准化您的数据
这是 vue.js 团队成员 [此处][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中提到的第二种方法:
When adding new properties to an Object, you should either:
Use Vue.set(obj, 'newProp', 123)
, or
Replace that Object with a fresh one
...
您可以使用另一个库轻松实现此目的: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
所做的更改。如果您不想 normalize/denormalize 您的数据,这种方法是可取的。
我正在尝试在 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 Store 内部的数组添加和删除元素?
我通常使用 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)
}
}
首先要了解的是 vuex
或任何其他基于 flux
体系结构的状态管理库并非旨在处理嵌套对象图,更不用说 arbitrary/infinity您提到的嵌套对象。更糟糕的是,即使使用浅状态对象,vuex
在 define the shape of the state (all desired fields) upfront.
恕我直言,您可以采取两种可能的方法
1。标准化您的数据
这是 vue.js 团队成员 [此处][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中提到的第二种方法:
When adding new properties to an Object, you should either:
Use
Vue.set(obj, 'newProp', 123)
, orReplace that Object with a fresh one
...
您可以使用另一个库轻松实现此目的: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
所做的更改。如果您不想 normalize/denormalize 您的数据,这种方法是可取的。