什么情况下需要重写 $listeners 的 input & change 监听事件

156 阅读1分钟

参考文章:# 探索Vue高阶组件

子组件:

<template>
  <div>
    <el-cascader
      v-model="cascaderValue"
      :options="options"
      
      v-bind="$attrs"
      v-on="$newListeners"
    />
    <el-input
      v-model="inputValue"
      
      v-bind="$attrs"
      v-on="$newListeners"
    >
    </el-input>
  </div>
</template>
computed: {
  $newListeners() {
    return {
      ...this.$listeners,
      // 一定要重写input&change方法,否则会调用父组件的input&change,
      // 从而修改父组件通过v-model绑定的值,即本组件prop中的value。
      // 继而引发类型问题。
      input: this.handleChange,
      change: this.handleChange
    };
  }
},
  • 问:什么情况下需要重写input & change监听事件?
  • 答:类似本组件中有两个输入框/表单栏的。或者说外部绑定的值会在本组件中解析为两个值。

  • 问:为什么 input & change 都绑定了this.handleChange

  • 答:为了保持一致性。不管是cascader还是input修改,都能保证最终结果的一致性。

    一定要重写input&change方法,否则会调用父组件的input&change,
    从而修改父组件通过v-model绑定的值,即本组件prop中的value。
    继而引发类型问题。
    
created() {
  // 可以处理一些请求,比如请求cascader的下拉选option数组
  this.init();
},
methods: {
    handleChange() {s
        ……处理数据
        const childComponentsValue = {
            cascader: this.cascaderValue,
            input: this.inputValue
        }
        // 下面两个emit调用父组件的input&change方法
        this.$emit('input', childComponentsValue);
        this.$emit('change', childComponentsValue);
    }
}
watch: {
  parentsComponentsValue: {
    handler(val, oldVal) {
      // 处理数据,外部数据被修改,同样会透传进该子组件中
      // 将数据处理回可以在子组件中回显的样子
      this.cascaderValue = val.cascader;
      this.inputValue = val.input;
    },
    immediate: true,
    deep: true
  }
},