文章目录
- 前言
- 一、button组件
- 二、属性
- 1,样式相关的属性
- 2.功能性
- 三、button-group
前言
今天主要是解析button按钮组件,相对来说是个很简单的组件。但是我想介绍一下我学习源码的方法,也欢迎讨论学习的方法。
我会自己搭一个vue2的框架,然后引入放在component
文件夹下的组件,组件与源码中组件结构保持一致,且兼顾按需导入和全局导入。
然后main.js
全局导入,并通过路由
分别演示不同组件,下面就是以radio单选框为例
我会复制源码过来,演示所有element官方文档的所有功能。然后下一步我认为比较关键,我会把多余的类名,处理函数等等全部删除只保留关键结构,一步一步跟着源码思路去实现所有的功能,在这个过程中理解吸收。
一、button组件
下面就是我删掉多余的属性后的主要结构。一目了然,一个原生html标签button,内含一个插槽,绑定一个向外触发事件和父组件交互并传出数据。
<template>
<button
class="el-button"
@click="handleClick"
>
<span ><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'ElButton',
methods: {
handleClick(evt) {
this.$emit('click', evt);
}
}
};
</script>
二、属性
1,样式相关的属性
<button
class="el-button"
@click="handleClick"
:class="[
type ? 'el-button--' + type : '',
buttonSize ? 'el-button--' + buttonSize : '',
{
'is-disabled': buttonDisabled,
'is-loading': loading,
'is-plain': plain,
'is-round': round,
'is-circle': circle
}
]"
>
<span ><slot></slot></span>
</button>
处理方式都一样,根据传参绑定类名,然后scss设置类名样式。下面就以type为例解析一下button对于样式的处理。
@include b(button) {
...
@include m(primary) {
@include button-variant($--button-primary-font-color, $--button-primary-background-color, $--button-primary-border-color);
}
@include m(success) {
@include button-variant($--button-success-font-color, $--button-success-background-color, $--button-success-border-color);
}
@include m(warning) {
@include button-variant($--button-warning-font-color, $--button-warning-background-color, $--button-warning-border-color);
}
@include m(danger) {
@include button-variant($--button-danger-font-color, $--button-danger-background-color, $--button-danger-border-color);
}
@include m(info) {
@include button-variant($--button-info-font-color, $--button-info-background-color, $--button-info-border-color);
}
}
这里对于@include b
和@include m
不进行赘述,不明白的朋友可以去看第二章 layout组件那篇文章有做详细解析。
上方scss代码编译为.el-button--primary{}
,但是内容中出现了@include button-variant
,我们继续追源码。
@mixin button-variant($color, $background-color, $border-color) {
color: $color;
background-color: $background-color;
border-color: $border-color;
&:hover,
&:focus {
background: mix($--color-white, $background-color, $--button-hover-tint-percent);
border-color: mix($--color-white, $border-color, $--button-hover-tint-percent);
color: $color;
}
&:active {
background: mix($--color-black, $background-color, $--button-active-shade-percent);
border-color: mix($--color-black, $border-color, $--button-active-shade-percent);
color: $color;
outline: none;
}
&.is-active {
background: mix($--color-black, $background-color, $--button-active-shade-percent);
border-color: mix($--color-black, $border-color, $--button-active-shade-percent);
color: $color;
}
&.is-disabled {
&,
&:hover,
&:focus,
&:active {
color: $--color-white;
background-color: mix($background-color, $--color-white);
border-color: mix($border-color, $--color-white);
}
}
&.is-plain {
@include button-plain($background-color);
}
}
看到这段源码,我觉得scss作为预编译的样式语言,不能体现出编程思想单纯的使用嵌套是没必要用scss。之前对scss的使用真的太浅了。
@mixin button-variant($color, $background-color, $border-color)
接收三个参数(color字体颜色,background-color背景颜色,border-color边框颜色)另外定义了button-active-shade-percent颜色混淆比例 mix() scss内置函数
不明白的可以去看第三章颜色那一章。
然后通过伪类定义focus聚焦,hover移动,active激活的样式
然后通过is-xxx,定义不同状态下的颜色深浅变化
2.功能性
代码如下:
<button
class="el-button"
@click="handleClick"
:disabled="buttonDisabled || loading"
:autofocus="autofocus"
:type="nativeType"
>
<span><slot></slot></span>
</button>
disabled禁用,loading加载,autofocus自动聚焦,type原始类型。由于button确实挺简单的也没太多可解析的。
三、button-group
看一下源码,就是给按钮编组没有任何逻辑上的处理,是样式上的编成一组,这种是符合ui设计原则的,相似功能的东西编组。
<template>
<div class="el-button-group">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'ElButtonGroup'
};
</script>
通过.el-button-group
类名做了编组的样式处理