在我的 Vue 应用程序中,我有 Vuex 存储模块,其状态中包含大量资源对象。为了轻松访问这些数组中的单个资源,我制作了 Vuex getter 函数,将资源或资源列表映射到各种键(例如“id”或“tags”)。这导致性能低下和巨大的内存内存占用。如何在没有这么多重复数据的情况下获得相同的功能和 react 性?
商店模块示例
export default {
state: () => ({
all: [
{ id: 1, tags: ['tag1', 'tag2'] },
...
],
...
}),
...
getters: {
byId: (state) => {
return state.all.reduce((map, item) => {
map[item.id] = item
return map
}, {})
},
byTag: (state) => {
return state.all.reduce((map, item, index) => {
for (let i = 0; i < item.tags.length; i++) {
map[item.tags[i]] = map[item.tags[i]] || []
map[item.tags[i]].push(item)
}
return map
}, {})
},
}
}
组件示例
export default {
...,
data () {
return {
itemId: 1
}
},
computed: {
item () {
return this.$store.getters['path/to/byId'][this.itemId]
},
relatedItems () {
return this.item && this.item.tags.length
? this.$store.getters['path/to/byTag'][this.item.tags[0]]
: []
}
}
}
最佳答案
要解决此问题,请引用编程中一种古老的标准做法:索引。您可以将映射存储到 state.all
中的项目索引,而不是在 getter 中存储一个包含完整项目值的映射。然后,您可以创建一个新的 getter,它返回一个函数来访问单个项目。根据我的经验,索引 getter 函数总是比旧的 getter 函数运行得更快,而且它们的输出占用的内存空间要少得多(在我的应用程序中平均减少 80%)。
新商店模块示例
export default {
state: () => ({
all: [
{ id: 1, tags: ['tag1', 'tag2'] },
...
],
...
}),
...
getters: {
indexById: (state) => {
return state.all.reduce((map, item, index) => {
// Store the `index` instead of the `item`
map[item.id] = index
return map
}, {})
},
byId: (state, getters) => (id) => {
return state.all[getters.indexById[id]]
},
indexByTags: (state) => {
return state.all.reduce((map, item, index) => {
for (let i = 0; i < item.tags.length; i++) {
map[item.tags[i]] = map[item.tags[i]] || []
// Again, store the `index` not the `item`
map[item.tags[i]].push(index)
}
return map
}, {})
},
byTag: (state, getters) => (tag) => {
return (getters.indexByTags[tag] || []).map(index => state.all[index])
}
}
}
新组件示例
export default {
...,
data () {
return {
itemId: 1
}
},
computed: {
item () {
return this.$store.getters['path/to/byId'](this.itemId)
},
relatedItems () {
return this.item && this.item.tags.length
? this.$store.getters['path/to/byTag'](this.item.tags[0])
: []
}
}
}
变化看似很小,但在性能和内存效率方面却产生了巨大的差异。它仍然是完全响应式的,就像以前一样,但您不再复制内存中的所有资源对象。在我的实现中,我抽象出了各种索引方法和索引扩展方法,使代码非常易于维护。
您可以在 github 上查看完整的概念证明,此处:https://github.com/aidangarza/vuex-indexed-getters
关于javascript - 使用 Vuex 在 Vue 应用程序中高效地处理大型数据集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52671666/