按照element-ui文档的顺序,button后的第二个组件就是radio了。
第一眼看到的就是class的绑定不一般,罒ω罒
:class="[
border && radioSize ? 'el-radio--' + radioSize : '',
{ 'is-disabled': isDisabled },
{ 'is-focus': focus },
{ 'is-bordered': border },
{ 'is-checked': model === label }
]"
复制代码
对着vue文档的Class绑定一节看了半天,发现数组绑定是有对象绑定不能替代的部分,即
border && radioSize ? 'el-radio--' + radioSize : '',
复制代码
className可以变化,所以class的数组绑定方式是万金油的写法(虽然有些繁琐)。(className用了is-*
,讲究)
第二眼就看到了aria-*
,这为辅助设备提供相应的标识(这也是为什么盲人也可以使用饿了么点外卖,点赞)
:aria-checked="model === label"
:aria-disabled="isDisabled"
复制代码
第三眼(真是每行都是精华呀)看到了:tabindex="tabIndex"
,这是规定页面元素的 tab 键控制次序,element-ui的表单元素支持按tab键选中,按enter或者space键点击的。
第四眼,radio的层级有很多,还不清楚是为什么,最后的html是
<span class="el-radio__label" @keydown.stop>
<slot></slot>
<template v-if="!$slots.default">{{label}}</template>
</span>
复制代码
这里对<el-radio></el-radio>
的标签中是否添加文字做了判断,如果添加文字,会放在$slots.default中。
最后统一讲一下值传递的过程:
当v-model用在组件上时,是这样的
<input v-model="searchText">
复制代码
等于
<custom-input
v-bind:value="searchText"
v-on:input="searchText = $event"
></custom-input>
复制代码
所以需要从props: { value: {}}
里取得在组件上用v-model绑定的值。
然后在计算方法里转换为绑定在真实radio上的值
<input
class="el-radio__original"
:value="label"
type="radio"
aria-hidden="true"
v-model="model"
复制代码
model即为下面计算方法中的model,同时起到了双向绑定的作用。值得注意的是,此处的set只提交了input改变,没提交change改变,从应用的角度来说,就是js修改而不是点击修改的,不会提交change(自己代码修改带来的变化自己处理,element只是更新数据了)
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);
}
}
},
复制代码
change方法是在nextTick,就是更新dom之后才提交更新,学到了,记笔记
this.$nextTick(() => {
this.$emit('change', this.model);
this.isGroup && this.dispatch('ElRadioGroup', 'handleChange', this.model);
});
复制代码
单选按钮组就添加了监控上下左右按键的监听,做了边界判断
case keyCode.LEFT:
case keyCode.UP:
e.stopPropagation();
e.preventDefault();
if (index === 0) {
roleRadios[length - 1].click();
roleRadios[length - 1].focus();
} else {
roleRadios[index - 1].click();
roleRadios[index - 1].focus();
}
break;
case keyCode.RIGHT:
case keyCode.DOWN:
if (index === (length - 1)) {
e.stopPropagation();
e.preventDefault();
roleRadios[0].click();
roleRadios[0].focus();
} else {
roleRadios[index + 1].click();
roleRadios[index + 1].focus();
}
break;
复制代码