如何优化实现数组元素新增/更新的VueX Mutation,精简代码提升性能
VueX Mutation 优化方案
原代码存在的问题
- 误用
Array.findAPI:find设计用途是返回匹配的元素,而非在遍历过程中修改状态,回调内掺杂副作用逻辑导致代码可读性差、调试成本高 - Vue 2 兼容性问题:直接通过索引
state.all[i] = data赋值无法触发数组的响应式更新,会导致视图不更新的隐性bug - 代码结构冗余,相同判断逻辑可以进一步简化
简化优化代码
Vue 3 环境(支持数组索引响应式)
PUSH_TO_ALL: (state, data) => { const index = state.all.findIndex(one => one.slug === data.slug) index === -1 ? state.all.push(data) : state.all[index] = data }
Vue 2 环境(兼容响应式)
// 需提前引入Vue import Vue from 'vue' // Mutation 代码 PUSH_TO_ALL: (state, data) => { const index = state.all.findIndex(one => one.slug === data.slug) index === -1 ? state.all.push(data) : Vue.set(state.all, index, data) }
进阶性能优化(仅适用于数组长度大于1000的场景)
如果state.all存储的对象量级很大,每次O(n)的查找会有性能损耗,可以新增slug到索引的映射表将查找耗时降到O(1):
// 1. 先修改state定义,新增映射表 state: { all: [], slugToIndex: new Map() } // 2. 改造Mutation PUSH_TO_ALL: (state, data) => { const existIndex = state.slugToIndex.get(data.slug) if (existIndex === undefined) { // 新增元素时同步记录索引 state.slugToIndex.set(data.slug, state.all.length) state.all.push(data) } else { state.all[existIndex] = data } } // 注意:如果存在删除`state.all`元素的Mutation,需要同步删除`slugToIndex`中对应的映射项
优化收益
- 核心逻辑代码行数减少60%,结构清晰无冗余,可维护性大幅提升
- 修复Vue 2环境下响应式失效的隐性问题
- 进阶优化版在大数据量场景下性能提升超过10倍
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

