先说问题,在点击el-radio时,需要先判断一下,根据判断结果决定本次点击是否有效,直接用v-model是实现不了这种效果的,所以就需要把v-model拆开——绑定value属性和监听它的input或change事件,在input或change中判断,真正需要起作用时把value绑定的值改掉。通过查看文档发现el-radio-group(因为我把el-radio放到了el-radio-group中)有change事件,就下意识的认为el-radio-group是通过value属性和change事件来实现v-model的。

// 模板长这样
<el-radio-group :value="radioValue" @change="handleChange">
	<el-radio lable="A">A</el-radio>
	<el-radio label="B">B</el-radio>
</el-radio-group>
// js长这样
data() {
return {
  radioValue: ''
},
methods: {
  handleChange(val) {
    console.log(val)
  }
}

然而,让我意想不到的事情发生了,每次change事件获取的都是value绑定的老值,并不能获取当前点击的el-radio的值,我凌乱了。

本着自我怀疑的态度,我盯着代码不下2分钟,怎么都想不通。终于无解!还是去看看源码怎么实现的吧。到node_modules/element-ui/packages/radio/src/radio.vue中找到了答案,

methods: {
      handleChange() {
        this.$nextTick(() => {
          this.$emit('change', this.model);
          this.isGroup && this.dispatch('ElRadioGroup', 'handleChange', this.model); // 这一行,它并不是简单的把当前radio的label传出去,而是把model传出去了
        });
      }
    }

让我们看看model究竟是什么

model: {
        get() {
          return this.isGroup ? this._radioGroup.value : this.value;
        },
        set(val) {
          if (this.isGroup) {
            this.dispatch('ElRadioGroup', 'input', [val]);
          } else {
            this.$emit('input', val);
          }
          this.$refs.radio && (this.$refs.radio.checked = this.model === this.label);
        }
      },

model是一个计算属性,如果当前el-radio是嵌套在el-radio-group中的就取el-radio-group的value。在我的应用场景里面,这显然是一个bug,我打算去element-ui的github上提issue了,在经过一番搜索后,我发现了https://github.com/ElemeFE/element/issues/10197,已经有人提了,竟然2018年就提了。element-ui的贡献者建议使用input事件,我就用input事件代替了change事件了,我的element-ui版本是2.15.6,我使用input确实能满足我的功能。

可能更多的还是先入为主了,看到文档中说有change事件,就想当然的认为双向绑定用了change事件。

如果对你有帮助,请点赞哈,嘻嘻:)

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐