elementUI源码分析-04-radio

一、基础回顾

el-radio是单选组件,是对原生的封装。

先来回顾原生的radio单选,比如做一个单选题的单选按钮

大苹果
大香蕉

checked:表示被选中的
value: 表示单选选项的值
name: 定义 input 元素的名称,具有相同name可以达到互斥的效果,表示同一时刻只能有一个按钮被选中

获取value的值,可以通过click、onchange等事件遍历元素,checked=true的那一项的value值,就是在最后选中的value值。

有时候还会input和label配合使用,label 元素不会向用户呈现任何特殊效果,label的for属性应当与相关元素的 id 属性相同,input配合label使用可以点击label的内容,聚焦到input

    
    


    
    

因为原生单选在不同浏览器下的默认显示效果不一样,所以通常情况下,我们都会采用障眼法覆盖其原生的样式。

    label{
    line-height: 24px;
    height: 24px;
    display: inline-block;
    margin-left: 5px;
    margin-right:15px;
    color: #777;
    }
    .radio_type{
    width: 20px;
    height:20px;
    appearance: none;
    -moz-appearance:none; /* Firefox */
        -webkit-appearance:none; /* Safari 和 Chrome */
    position: relative;
    }
    .radio_type:before{
    content: '';
    width: 20px;
    height: 20px;
    border: 2px solid #EDD19D;
    display: inline-block;
    border-radius: 50%;
    vertical-align: middle;
    }
    .radio_type:checked:before{
    content: '';
    width: 20px;
    height: 20px;
    border: 2px solid #EDD19D;
    display: inline-block;
    border-radius: 50%;
    vertical-align: middle;
    }
    .radio_type:checked:after{
    content: '';
    width: 12px;
    height: 12px;
    text-align: center;
    background:#EDD19D;
    border-radius: 50%;
    display: block;
    position: absolute;
    top: 6px;
    left: 6px;
    }
    .radio_type:checked+label{
    color: #EDD19D;
    }
image.png

二、el-radio用法与源码

el-radio

基础的引用方式如下:




接受的参数如下

参数 说明 类型 可选值 默认值
value / v-model 绑定值 string / number / boolean
label Radio 的 value string / number / boolean
disabled 是否禁用 boolean false
border 是否显示边框 boolean false
size Radio 的尺寸,仅在 border 为真时有效 string medium / small / mini
name 原生 name 属性 string

源码如下



name:用于给原生input元素的设置name属性,用于达到相同name互斥的效果

border: 是否为选项添加边框,如果为true,则设置is-bordered类名为元素添加边框

.el-radio.is-bordered {
    padding: 12px 20px 0 10px;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    height: 40px;
}

size:与border配合使用时才生效,用来设置选项按钮大小

disabled:给原生input元素设置disable属性,使其禁用。

label:Radio 的 value值

value / v-model:用来实现双向数据绑定的。

三、功能点解密

样式设置

el-redio样式

el-radio也是覆盖了radio原有的样式。label下面嵌套了2个span,第一个span是图标部分,第二个span是文字部分,

第一个span中又嵌套了一个span和input,里面的span是模拟的圆形按钮,input是真正的radio标签,el-input隐藏了原有的input样式,然后用span标签去模拟input标签。

隐藏原生input的样式,将其设置opacity为0,使其在页面中不可见,但是可以点击

.el-radio__original {
    opacity: 0;
    outline: none;
    position: absolute;
    z-index: -1;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    margin: 0;

设置span的样式,模拟input

// 空心,未选中转台的按钮
.el-radio__inner {
    border: 1px solid #dcdfe6;
    border-radius: 100%;
    width: 14px;
    height: 14px;
    background-color: #fff;
    position: relative;
    cursor: pointer;
    display: inline-block;
    box-sizing: border-box;
}
空心 未选中转台的按钮
// 选中状态下的按钮
el-radio__input.is-checked .el-radio__inner {
    border-color: #409eff;
    background: #409eff;
}
.el-radio__inner {
    border: 1px solid #dcdfe6;
    border-radius: 100%;
    width: 14px;
    height: 14px;
    background-color: #fff;
    position: relative;
    cursor: pointer;
    display: inline-block;
    box-sizing: border-box;
}
//  用伪类,模拟中间小圆点
.el-radio__input.is-checked .el-radio__inner:after {
    transform: translate(-50%,-50%) scale(1);
}
.el-radio__inner:after {
    width: 4px;
    height: 4px;
    border-radius: 100%;
    background-color: #fff;
    content: "";
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%,-50%) scale(0);
    transition: transform .15s ease-in;
}

v-model/value

单独引用el-radio组件的时候,都会使用v-model去绑定data下面的值来实现双向数据绑定,也就是说有时候即使我们不设置name属性,也可以达到互斥的效果,所以我们去看下v-model/value是如何实现的呢?

其实v-model/value只是v-bind和v-on的语法糖,在使用v-model绑定数据以后,既绑定了数据,又添加了事件监听,这个事件就是input事件。

官方文档给出:


这不过是以下示例的语法糖:


这就相当于对input元素的input事件进行监听,来实现value值的绑定,至于如何实现互斥,其实就是如果单选框的value值和v-model值相同,那么就给当前input元素添加一个checked属性,表示被选中,其他不相等的,就不添加checked属性,就实现了互斥的效果。

在el-radio的源码中,对input设置的是v-model="model",并且对model设置了getter和setter,然后emit一个input事件,在官网中可以看到解释.

允许一个自定义组件在使用 v-model 时定制 prop 和 event。默认情况下,一个组件上的 v-model 会把 value 用作 prop 且把 input 用作 event。


上述代码相当于



tabindex和:aria-&

tabIndex和aria-* 都是属于无障碍学习的一些设置。

html中的tabIndex属性可以设置键盘中的TAB键在控件中的移动顺序,即焦点的顺序。几乎所有浏览器均 tabindex 属性,除了 Safari。

tabindex有三个值:0 ,-1, 以及X(X里32767是界点)。

当tabindex>=1时,该元素可以用tab键获取焦点,数字越小,越先定位到。

tabIndex=0 ,将排列在所有tabIndex>=1的控件之后。默认情况下tabIndex=0

当tabindex=-1时,该元素用tab键获取不到焦点,但是可以通过js获取.

支持 tabindex 属性的元素:, ,