Vue3深度监听器无法访问对象数组中指定对象属性的问题
问题分析与解决方案
1. 代码笔误修正
你的代码中store.getRule..find存在多余的点,应改为store.getRule.find,否则会直接抛出语法错误。
2. 核心问题:数组项为undefined
报错Cannot read properties of undefined (reading 'data')说明监听器回调中的val[0]或val[1]本身是undefined,大概率是Pinia的rule数组未初始化完成,导致find方法找不到对应key的项,root或leaf1为undefined,最终listCollection被赋值为[undefined, undefined]。
解决办法:
赋值前先校验目标项是否存在,避免将undefined加入数组:
const root = store.getRule.find(e => e.key === 'root') const leaf1 = store.getRule.find(e => e.key === 'leaf1') // 确认找到目标项后再赋值 if (root && leaf1) { listCollection.value = [{...root}, {...leaf1}] } else { console.warn('未找到root或leaf1规则项') }
3. 规避Pinia代理对象的影响
Pinia的state是Vue响应式代理对象,直接展开{...root}可能导致响应式特性丢失或出现异常行为。建议用toRaw将代理对象转为普通对象后再复制:
import { toRaw } from 'vue' const root = store.getRule.find(e => e.key === 'root') const leaf1 = store.getRule.find(e => e.key === 'leaf1') if (root && leaf1) { listCollection.value = [toRaw(root), toRaw(leaf1)] }
4. 监听器增加安全判断
即使前面的处理都完成,也建议在监听器回调中增加安全校验,避免数组结构变化导致报错:
watch(listCollection, (val) => { if (val[0]) { console.log(val[0].data) } if (val[1]) { console.log(val[1].data) } }, { deep: true })
5. 确保响应式更新正常
如果select-list组件修改item.data需要触发监听器,需确保listCollection中的对象是响应式的。若使用ref数组,展开后的普通对象无法触发响应式更新,可改为reactive数组:
import { reactive } from 'vue' const listCollection = reactive([]) if (root && leaf1) { listCollection.push(toRaw(root), toRaw(leaf1)) }
内容的提问来源于stack exchange,提问作者Ludwig Loth
相关产品推荐
相关产品推荐

