我有一个支持v-model
的自定义组件。相符内部值的表示形式与原始输入完全不同,但是在组件内部使用起来很方便。该组件的职责是转换值,并让用户以复杂的形式对其进行更改。此外,该组件应响应来自父组件的v-model
的更改,即它应注意value
的更改。
我的代码:
export default {
props: ['value'],
data() {
return {innerValue: undefined};
},
mounted() {
this.calculateInnerValue();
},
methods: {
calculateInnerValue() {
this.innerValue = /* very heavy transformation based on this.value */;
},
onUserChange() {
const value = /* very heavy transformation based on this.innerValue */;
this.$emit('input', value);
}
},
watch: {
value() {
this.calculateInnerValue();
}
}
}
问题在于,只要此组件触发
input
事件,就会触发监视,从而导致不需要的calculateInnerModel
调用。有什么好的方法可以防止这种行为,同时保持对其他来源的父值更改的响应?
我可以拿出一个旗帜,例如
calculateInnerValue() {
if (!this.itsMeChanging)
this.innerValue = /* very heavy computation based on this.value */;
},
onChange() {
const value = /* very heavy computation based on this.innerValue */;
this.itsMeChanging = true;
this.$emit('input', value);
this.itsMeChanging = false;
}
但是,正如您所看到的,这很好。
Github上的相关问题:https://github.com/vuejs/vue/issues/1829
最佳答案
您可以做的一件事是保留对未转换的value
属性的引用,然后仅在观察器中的calculateInnerValue
与子组件的引用不同的情况下才调用value
方法。
这是一个示例,其中innerValue
现在对应于从父级传入的value
属性的未转换值,并且转换后的值现在设置为transformedValue
数据属性:
export default {
props: ['value'],
data() {
return {
innerValue: this.value,
transformedValue: undefined
};
},
mounted() {
this.calculateTransformedValue();
},
methods: {
calculateTransformedValue() {
this.transformedValue = /* very heavy transformation based on this.innerValue */;
},
onUserChange() {
this.innerValue = /* very heavy transformation based on this.transformedValue */;
this.$emit('input', this.innerValue);
}
},
watch: {
value(value) {
if (value !== this.innerValue) {
this.calculateTransformedValue();
this.innerValue = value;
}
}
}
}
您还可以通过将
transformedValue
设为基于innerValue
的计算属性来进一步简化代码:export default {
props: ['value'],
data() {
return {
innerValue: this.value
};
},
computed: {
transformedValue() {
return /* very heavy transformation based on this.innerValue */
}
},
methods: {
onUserChange() {
this.innerValue = /* very heavy transformation based on this.transformedValue */;
this.$emit('input', this.innerValue);
}
},
watch: {
value(value) {
this.innerValue = value;
}
}
}
关于vue.js - 不要观看自己的v模型更新,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57463191/