You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 03:10:20