共计 1656 个字符,预计需要花费 5 分钟才能阅读完成。
概述
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 事件就可以了;事实证明是不可以的,为什么呢?