事情是这样的,我接到的需求是要做一个表单的动态效果,预期效果如图:
也就是更改了之后会把对应表单的标签变成红色,现在出现的问题是,当我操作其他数据的时候,即使我没有做更改他也会报错误高亮
这是全局指令的相关代码
export default {
bind(el, binding, vnode) {
resetInitialState(vnode); // 重置初始状态
},
inserted(el, binding, vnode) {
vnode.context.$nextTick(() => {
initializeState(el, binding, vnode);
});
},
update(el, binding, vnode, oldVnode) {
if (binding.value !== binding.oldValue) {
vnode.context.$nextTick(() => {
let id = vnode.context.form.id
let newVal = binding.value
let oldValue = binding.oldValue
let edited = false
if (id && newVal !== undefined && oldValue !== undefined) {
if (newVal !== oldValue) {
edited = true
}
}
updateLabelStyle(el, edited);
initializeState(el, binding, vnode);
});
}
},
unbind(el, vnode) {
resetInitialValues(vnode); // 重置初始值
if (el._observer) {
el._observer.disconnect();
}
},
};
function updateLabelStyle(el, edited) {
const labelElement = el.querySelector('label');
if (labelElement) {
edited ? labelElement.classList.add('edited-label') : labelElement.classList.remove('edited-label');
}
}
function resetInitialState(vnode) {
vnode.context.initialValues = {};
}
function resetInitialValues(vnode) {
const instanceUid = vnode.context._uid;
if (vnode.context.initialValues && vnode.context.initialValues[instanceUid]) {
delete vnode.context.initialValues[instanceUid];
}
}
function initializeState(el, binding, vnode) {
const propName = binding.expression;
const instanceUid = vnode.context._uid;
let initialValues = vnode.context.initialValues;
if (!initialValues) {
vnode.context.initialValues = initialValues = {};
}
if (!initialValues[instanceUid]) {
initialValues[instanceUid] = {};
}
const isNewForm = binding.modifiers.new;
if (isNewForm) {
initialValues[instanceUid][propName] = null;
} else if (initialValues[instanceUid][propName] === undefined) {
initialValues[instanceUid][propName] = JSON.stringify(binding.value);
}
const updateLabelStyle = (edited) => {
const labelElement = el.querySelector('label');
if (labelElement) {
edited ? labelElement.classList.add('edited-label') : labelElement.classList.remove('edited-label');
}
};
const updateLabelColor = (newVal) => {
let newValue = newVal === undefined || newVal === '' ? '' : JSON.stringify(newVal);
updateLabelStyle(newValue !== initialValues[instanceUid][propName]);
};
updateLabelColor(binding.value);
vnode.context.$watch(propName, (newVal) => {
vnode.context.$nextTick(() => {
updateLabelColor(newVal);
});
}, { deep: true });
const updateLabelCallback = () => updateLabelColor(vnode.context[propName]);
const classList = ['el-select', 'el-radio-group', 'el-input-number', 'el-checkbox-group', 'el-date-picker'];
for (const className of classList) {
if (el.classList.contains(className)) {
el._observer = observeElement(el.querySelector(`.${className.split('-').slice(-1)[0]}`), updateLabelCallback);
break;
}
}
}
function observeElement(element, callback) {
if (element) {
const observer = new MutationObserver(callback);
observer.observe(element, {
attributes: true,
childList: true,
subtree: true,
});
return observer;
}
}
最好是能远程帮看一下