概述ui库用的是iview . radio、radioGroup是我们非常常用的组件。radio有一个特征是选中之后无法取消。现实中取消radio的需求是常见且可以理解的。所以看到这个需求之后第一尝试 在iview组件之上搞一搞,这一搞就入坑了,现在就来理一理我的入坑之路吧。1. 原生组件radio的取消首先我们来看一下在 vue 中使用原生的radio组件如何使用取消。 原生radio取消选中的文章非常多,随便拎一篇看看就行,比如 取消radio的三种方法。嗯,原理就是给radio元素的checked属性赋值为 false。具体在 vue 中使用是这样的:const { name, value } = data;<div> <input class=“xxx” type=“radio” name={this.id} ref={name} value={value} onClick={(vlaue) => this.radioGroupChange(value, name)} /> {name}</div>;// 方法radioGroupChange (value, name) { if (this.checked === value) { // 取消选中 this.$refs[name].checked = false; // 当前选中值为空 this.checked = ‘’; } else { this.checked = value; }}这样就OK了。大概唯一区别是 在 vue中通过 ref取到真实 dom。2. iview中radio取消之路借鉴原生的radio,看来取消也不难嘛,监听radio或者 radio的change事件嘛。然而你会发现,重复点选某一个 radio的时候,iview中的on-change函数跟本木有响应。这是为什么呢? 去 iview 源码中看一看2.1 iview组件radio源码探究先上代码为敬:先看下 radio.vue的 template<template> <label :class=“wrapClasses”> <span :class=“radioClasses”> <span :class=“innerClasses”></span> <input type=“radio” :class=“inputClasses” :disabled=“disabled” :checked=“currentValue” :name=“groupName” @change=“change” @focus=“onFocus” @blur=“onBlur”> </span><slot>{{ label }}</slot> </label></template>再看下 change的响应函数 change (event) { // debugger if (this.disabled) { return false; } const checked = event.target.checked; this.currentValue = checked; const value = checked ? this.trueValue : this.falseValue; this.$emit(‘input’, value); if (this.group) { if (this.label !== undefined) { this.parent.change({ value: this.label, checked: this.value }); } } else { this.$emit(‘on-change’, value); this.dispatch(‘FormItem’, ‘on-form-change’, value); }},一开始怀疑 change事件中对 value做了处理,只有 不一样的时候才 emit,仔细看,change函数中并没有这部分处理。问题在于 input 这里监听的 change 事件而不是 click事件,所以反复点击同一个 radio的时候没有 响应是正常的。2.2 如何监听到 click事件看到上面是不是就想 我在 radio上绑定一个click 事件就可以了;事实证明是不可以的,为什么呢?