ShiningDan的博客

一天一个 Element 组件 - Button

本文是 Element 的组件源码学习系列。

项目源码:ElemeFE/element | GitHub,Tag:v2.13.0

Button 组件使用文档:Button 按钮

.vue 文件:/packages/button

.scss 文件:/packages/theme-chalk/button.scss

.d.ts 文件:/types/button.d.ts

el-button 的实现比较简单,基于原生 button 按钮

Template

如果在 el-button 中设置了 icon 属性,则按钮的文字前面会出现对应的 Icon。并且 el-button 支持包裹文字。

1
2
3
4
5
6
7
8
## 源码
<template>
<button
<i :class="icon" v-if="icon && !loading"></i>
<span v-if="$slots.default"><slot></slot></span>
>
</button>
</template>

JS

computed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
## 源码
<template>
<button
:disabled="buttonDisabled || loading"
:class="[
buttonSize ? 'el-button--' + buttonSize : '',
]"
>
</button>
</template>
<script>
export default {
name: 'ElButton',

inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},

computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
buttonSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
buttonDisabled() {
return this.disabled || (this.elForm || {}).disabled;
}
},
}
</script>

computed 里面,处理了 buttonSizebuttonDisabled 的逻辑,我们先来看一下 buttonSize

buttonSize

buttonSize 的优先级是:

  1. 本身设置的 size 属性
  2. 包裹自身的 el-form-item 设置的 size 属性。因为在表单中,我们经常对在 el-form 或者 el-form-item 上面设置表单元素的大小
  3. 全局尺寸设置 this.$ELEMENT

inject 为高阶插件/组件库提供用例。允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。在这里,说明,如果 el-button 被包裹在 el-form 或者 el-form-item 中,则通过 this.elFormthis.elFormItem 就可以拿到包裹自身的组件。

全局尺寸设置 this.$ELEMENT,在入口文件 src/index.ts 中设置:

1
2
3
4
5
// 全局设置尺寸
Vue.prototype.$ELEMENT = {
size: opts.size || '',
zIndex: opts.zIndex || 2000
};

buttonDisabled

参考 buttonSize 的逻辑,buttonDisabled 的优先级是:

  1. 本身设置的 disable 属性
  2. 包裹这个按钮的表单 el-form 设置的 disable 属性

click 事件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 源码
<template>
<button
@click="handleClick">
</button>
</template>
<script>
export default {
methods: {
handleClick(evt) {
this.$emit('click', evt);
}
}
}
</script>

## 使用示例
<el-button
@click="count++">
</el-button>

click 事件的逻辑不复杂。el-button 的实现方案是基于 HTML button 元素,也就是渲染在页面上的时候,实际是一个 button 元素,用户点击的时候,触发的也是 buttonclick 事件。

当用户点击按钮的时候,会调用 handleClick 函数,触发一个 el-button 的 click 事件。如果用户给 el-button 赋值了 @click 函数,如示例中的 count++,则该函数会被执行。

CSS

CSS 相关的源码解读,之后再补充