Vue监听嵌套数组:如何标记info_array的触达字段?
解决嵌套数组字段的触达标记问题
原代码仅能识别顶层字段(如seller_id)的变更,无法检测info_array这类嵌套数组/对象内部字段的修改——核心原因是直接对比引用类型的内存地址无法感知内部属性变化,且未递归遍历嵌套结构。
以下是修正后的实现方案:
const form = useForm('post', route('dashboard.purchases.store'), { seller_id: 0, info_array: [{ title_id: 0, price_usd: '', price_gel: '', quantity: '' }] }) let touchedFields = new Set(); // 递归遍历新旧数据,返回所有变更字段的完整路径 function findChangedFields(newData, oldData, parentPath = '') { const changed = []; // 处理数组类型 if (Array.isArray(newData) && Array.isArray(oldData)) { for (let i = 0; i < newData.length; i++) { const currentPath = parentPath ? `${parentPath}[${i}]` : `[${i}]`; if (typeof newData[i] === 'object' && newData[i] !== null && typeof oldData[i] === 'object' && oldData[i] !== null) { changed.push(...findChangedFields(newData[i], oldData[i], currentPath)); } else if (newData[i] !== oldData[i]) { changed.push(currentPath); } } return changed; } // 处理对象类型 if (typeof newData === 'object' && newData !== null && typeof oldData === 'object' && oldData !== null) { const allKeys = new Set([...Object.keys(newData), ...Object.keys(oldData)]); for (const key of allKeys) { const currentPath = parentPath ? `${parentPath}.${key}` : key; if (typeof newData[key] === 'object' && newData[key] !== null && typeof oldData[key] === 'object' && oldData[key] !== null) { changed.push(...findChangedFields(newData[key], oldData[key], currentPath)); } else if (newData[key] !== oldData[key]) { changed.push(currentPath); } } return changed; } // 基础类型直接对比 return newData !== oldData ? [parentPath] : []; } watch(() => form.data(), (newData, oldData) => { const changedFields = findChangedFields(newData, oldData); changedFields.forEach(field => touchedFields.add(field)); console.log(touchedFields); }, { deep: true })
关键说明:
findChangedFields函数会递归遍历数据的每一层,生成具体的字段路径(如info_array[0].price_gel),不管是顶层字段还是嵌套数组/对象内的字段,只要发生变更都会被捕获。- 最终
touchedFields集合会记录所有被修改过的字段完整路径,比如修改info_array中第一个元素的title_id,集合中会新增info_array[0].title_id。
内容的提问来源于stack exchange,提问作者Anry Reese
相关产品推荐
相关产品推荐

