Vue前端遇到的bug问题

事情是这样的,拿到的需求是,当用户修改输入框内的内容的时候,只要检测到有修改就自动把对应的标签变成红色,如图:

就是这种效果,这些效果我也实现了的,接下来描述遇到的问题:
问题复现:
在操作第一条数据的时候一切都是正常的,然后在操作第二条数据的时候就出现了这种情况

然后我调试了再检查了一下:

我发现当第二条的相关数据与第一条内的数据一致的时候就显示正常了,然后我判断这个渲染标题颜色的高亮规则肯定是拿了第一条数据做对比了,以上的代码完全是用ChatGPT来完成的,用的是Vue的全局指令来进行渲染的,以下是源代码:

export default {
  inserted(el, binding, vnode) {
    initializeState(el, binding, vnode);
  },

  update(el, binding, vnode, oldVnode) {
    // 只有当currentDataItemId改变时,我们才重新初始化状态。
    if (vnode.context.currentDataItemId !== oldVnode.context.currentDataItemId) {
      initializeState(el, binding, vnode);
    }
  },

  unbind(el) {
    // 如果有observer,则停止观察
    if (el._observer) {
      el._observer.disconnect();
    }

    const labelElement = el.querySelector('label');
    if (labelElement) {
      labelElement.style.color = '';
    }
  },
};


function areValuesEqual(value1, value2) {
  return JSON.stringify(value1) === JSON.stringify(value2);
}

function initializeState(el, binding, vnode) {
  const propName = binding.expression;
  const currentUid = vnode.context._uid;
  const key = `${currentUid}_${propName}`;
  console.log(`Initializing state for key=${key}`);

  // 尝试从组件状态中获取editedStates
  let editedStates = vnode.context.editedStates;

  // 获取当前数据项的唯一标识符,例如ID或其他能区分数据项的字段
  const currentDataItemId = vnode.context.currentDataItemId;

  // 如果不存在,则创建一个新对象并存储在组件状态中
  if (!editedStates) {
    vnode.context.editedStates = editedStates = {};
  }

  // 创建或获取当前数据项的编辑状态
  let localEditedState = editedStates[currentDataItemId];
  if (!localEditedState) {
    localEditedState = editedStates[currentDataItemId] = {};
  }

  vnode.context.$on('reset-form', () => {
    // 重置表单状态
    localEditedState[key] = {
      edited: false,
      initialValue: JSON.stringify(binding.value),
    };
    console.log(`Resetting state for ${key}`);
    // 还原标签颜色
    el.querySelector('label').style.color = '';
  });

  // 只在第一次插入时设置初始值
  if (!localEditedState[key]) {
    const initialValue = JSON.stringify(binding.value);
    console.log(`Setting initial value: key=${key}, initialValue=${initialValue}`);
    localEditedState[key] = {
      edited: false,
      initialValue: initialValue,
    };
  }

  const updateLabelColor = (newVal) => {
    const propertyState = localEditedState[key];

    let newValue = newVal;
    if (newVal === undefined || newVal === '') {
      newValue = propertyState.initialValue === JSON.stringify('') ? '' : undefined;
    } else {
      newValue = JSON.stringify(newVal);
    }

    console.log(`updateLabelColor: key=${key}, newValue=${newValue}, initialValue=${propertyState.initialValue}`);

    if (newValue !== propertyState.initialValue) {
      propertyState.edited = true;
      console.log(`Setting color to red for ${key}`);
      el.querySelector('label').style.color = 'red';
    } else {
      propertyState.edited = false;
      console.log(`Setting color to default for ${key}`);
      el.querySelector('label').style.color = '';
    }
  };

  vnode.context.$watch(propName, (newVal, oldVal) => {
    vnode.context.$nextTick(() => {
      if (!areValuesEqual(newVal, oldVal)) {
        console.log(`$watch triggered for ${key}, new value: ${JSON.stringify(newVal)}`);
        updateLabelColor(newVal);
      }
    });
  }, { deep: true });

  if (el.classList.contains('el-select')) {
    const selectElement = el.querySelector('.el-select-dropdown');
    if (selectElement) {
      const observer = new MutationObserver(() => {
        const newValue = vnode.context[propName];
        console.log(`MutationObserver triggered for ${key}, new value: ${JSON.stringify(newValue)}`);
        updateLabelColor(newValue);
      });
      observer.observe(selectElement, {
        attributes: true,
        childList: true,
        subtree: true,
      });
      // 将observer存储在元素上,以便以后停止观察
      el._observer = observer;
    }
  }
}

能帮远程一下吗,不太懂..

思路都是错的

【以下回答由 GPT 生成】

这个bug问题可能是由于在update函数中只比较了currentDataItemId是否改变,而没有比较其他数据是否改变导致的。你可以尝试在update函数中进行相应的增加判断,比较当前数据与旧数据的字段是否有修改,只有在字段发生变化时才重新初始化状态。

下面是修改的代码片段参考:

update(el, binding, vnode, oldVnode) {
  // 比较当前数据与旧数据是否有修改
  if (!areValuesEqual(vnode.context.currentDataItem, oldVnode.context.currentDataItem)) {
    initializeState(el, binding, vnode);
  }
}

此外,还需要确保你在initializeState函数中正确获取到了需要对比的数据项,比如currentDataItem和oldDataItem。

希望这些修改能够解决你遇到的bug问题。如果你还有其他疑问,请随时追问。



【相关推荐】



如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^