父/子组件对共享对象的更改无反应

时间:2018-08-01 10:44:41

标签: vue.js vue-component

我在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="{&quot;title&quot;: [&quot;This field is required&quot;]}"> <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

我现在被困在最后一件事上。

输入组件正在对错误收集中的更改做出反应,并删除或重新显示错误消息。

但是表单对更改没有反应,并且错误收集为空时,提交按钮也未启用。

我如何让父母对共享错误集合上的更改做出反应?还是在父表单和子表单输入之间共享状态的更好方法?

1 个答案:

答案 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可能可以使事情变得整洁。