如何通过Vue与Vuex的watch更新匹配ID的布尔属性
Vue+Vuex中通过watch更新对象数组的selected属性
需求
在Vue和Vuex中利用watch监听,当entry.items数组中对象的from_id与lists.from数组中对象的item_id匹配时,将对应lists.from对象的selected布尔值设为true。
现有数据结构(store.js)
entry: { items: [ { from_id: 5, to_id: 1, quantity: 100, }, { from_id: 11, to_id: 3, quantity: 119, }, { from_id: 7, to_id: 3, quantity: 59, }, ] } lists: { from: [ { item: {...}, item_id: 5, selected: false }, { item: {...}, item_id: 6, selected: false, }, { item: {...}, item_id: 7, selected: false, } ] } const getters = { entry: (state) => state.entry, lists: (state) => state.lists, };
尝试的无效代码
computed: { ...mapGetters('Conversion', ['entry', 'lists']), }, watch: { 'lists.from': { deep: true, handler: function (items) { const _itemsEntry = this.entry.items; let result; _itemsEntry.map((entry) => { result = items.filter((item) => item.item_id === entry.from_id ? { ...item, selected: true } : items ); }); console.log(result); }, }, },
问题分析
filter方法误用:filter的回调函数需要返回布尔值来筛选元素,你却返回修改后的对象或原数组,完全无法实现属性修改的目的。- 变量覆盖问题:在
map循环中每次给result赋值,最终result只会保留最后一次循环的结果,而非所有修改后的数组。 - 未修改原数组属性:你只是在
filter里创建了新对象,但没有将修改后的结果同步回原数组。 - Vuex状态修改不规范:直接在组件中修改Vuex状态不符合规范,开启严格模式时会报错,正确做法是通过mutation修改。
正确解决方案
步骤1:在Vuex Store中添加Mutation
首先在store的mutations中定义修改状态的方法:
const mutations = { UPDATE_FROM_LIST_SELECTED(state, matchedIds) { // 遍历lists.from,根据matchedIds更新selected状态 state.lists.from.forEach(item => { item.selected = matchedIds.includes(item.item_id); }); } };
步骤2:组件中实现Watch监听
同时监听entry.items和lists.from的变化,触发状态更新:
computed: { ...mapGetters('Conversion', ['entry', 'lists']), }, watch: { // 监听entry.items的深层变化 'entry.items': { deep: true, handler: function() { this.updateSelectedStatus(); } }, // 监听lists.from的深层变化 'lists.from': { deep: true, handler: function() { this.updateSelectedStatus(); } } }, methods: { // 映射Vuex的mutation ...mapMutations('Conversion', ['UPDATE_FROM_LIST_SELECTED']), updateSelectedStatus() { // 收集entry.items中所有的from_id const matchedIds = this.entry.items.map(entry => entry.from_id); // 调用mutation更新selected状态 this.UPDATE_FROM_LIST_SELECTED(matchedIds); } }
非规范方案(不推荐)
如果不需要遵循Vuex状态修改规范,也可以直接在组件中修改数组属性(仅适用于非严格模式):
computed: { ...mapGetters('Conversion', ['entry', 'lists']), }, watch: { 'entry.items': { deep: true, handler: function() { this.updateSelected(); } }, 'lists.from': { deep: true, handler: function() { this.updateSelected(); } } }, methods: { updateSelected() { const fromIds = this.entry.items.map(item => item.from_id); // 直接遍历修改selected属性 this.lists.from.forEach(listItem => { listItem.selected = fromIds.includes(listItem.item_id); }); } }
内容的提问来源于stack exchange,提问作者user19991216
相关产品推荐
相关产品推荐

