我在jsfiddle上举了一个例子:https://jsfiddle.net/j6hs5fmL/56/
对于这个问题,我创建了一个非常简单的html文档:
detectValueChange(index: number){
let controls = this.formGroup.get('products') as FormArray;
this.changeTotal(controls[index])
}
changeTotal(control) {
let price = parseFloat(control.value.product_price);
let quantity = parseInt(control.value.product_quantity);
if (!isNaN(price) && !isNaN(quantity)) {
let totalCost = (price * quantity).toFixed(2);
control['product_total'].setValue(totalCost, { emitEvent: false })
}
}
错误会传递到<div id="app">
<my-form errors="{"title": ["This field is required"]}">
<my-input name="title" value=""></my-input>
</my-form>
</div>
中,然后将其放入我创建的Collection类中:
my-form
然后Vue.component('my-form', {
name: 'my-form',
props: {
errors: String
},
data() {
let errors = new Collection(JSON.parse(this.errors));
return {
myErrors: errors,
disabled: errors.any()
}
},
template: `<form>
<slot></slot>
<input type="submit" :disabled="disabled" value="Submit">
</form>`
});
组件可以访问错误并显示错误:
my-input
我现在被困在最后一件事上。
输入组件正在对错误收集中的更改做出反应,并删除或重新显示错误消息。
但是表单对更改没有反应,并且错误收集为空时,提交按钮也未启用。
我如何让父母对共享错误集合上的更改做出反应?还是在父表单和子表单输入之间共享状态的更好方法?
答案 0 :(得分:1)
您的主要问题是您的Collection类没有反应性。它不是一个普通的对象,因此Vue不会对其元素上的访问器发挥作用。您需要在父对象中创建重新分配myErrors
本身的方法,以便Vue注意到更改:
methods: {
refresh() {
const temp = this.myErrors;
this.myErrors = null;
this.myErrors = temp;
},
set(field, value) {
this.myErrors.set(field, value);
this.refresh();
},
clear(field) {
this.myErrors.clear(field);
this.refresh();
}
},
my-input
不应将errors
作为data
项,因为它不是独立的数据对象。它应该是经过计算的:
errors() {
return this.$parent.myErrors;
}
您可能不应该使用blur
事件,而应该watch
进行value
的更新并调用父方法:
watch: {
value(newValue) {
if (newValue !== '') {
this.$parent.clear(this.name);
} else {
this.$parent.set(this.name, ['This input is still required']);
}
}
},
将所有内容放在一起,然后the fiddle works。这是插槽对象和父对象的相当紧密的耦合,但是inherent in your design是插槽必须了解父对象的某些知识。 scoped slots可能可以使事情变得整洁。