element-ui作为饿了吗开发的开源项目,现在github上已有超过40k的star(截至笔者发布日),故深入学习elementui的源码,不仅会对日后的使用上有所帮助,同时学习并借鉴项目中对于Vue的使用,同样会对自身有很大提升。
此系列将详细解析element-ui各组件的源码,第一部分就从较为简单的el-button开始。
首先,看此部分的文件结构:
先来看index.js:
import ElButton from './src/button';
ElButton.install = function(Vue) {
Vue.component(ElButton.name, ElButton);
};
export default ElButton;
此处导入了button组件,并暴露了install方法,这样我们就可以在需要的地方使用Vue.use使用el-button插件了。(这也是为何在使用element-ui的时候,需要用Vue.use的原因,关于install和use的具体说明可以查阅Vue官方文档)。
在分析源码前,我们先来看一下官方文档对于button的使用说明:
可以看出,el-button中定义的属性,基本上都是对button样式的操作(例如size:尺寸,type:类型,实际上就是颜色),此时再看核心组件的源码:
<template>
<!-- 通过传递不同的class,从而展示不同的样式 -->
<button
class="el-button"
@click="handleClick"
:disabled="buttonDisabled || loading"
:autofocus="autofocus"
:type="nativeType"
:class="[
type ? 'el-button--' + type : '',
buttonSize ? 'el-button--' + buttonSize : '',
{
'is-disabled': buttonDisabled,
'is-loading': loading,
'is-plain': plain,
'is-round': round,
'is-circle': circle
}
]"
>
<i class="el-icon-loading" v-if="loading"></i>
<i :class="icon" v-if="icon && !loading"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'ElButton',
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: {
type: {
type: String,
default: 'default'
},
size: String,
icon: {
type: String,
default: ''
},
nativeType: {
type: String,
default: 'button'
},
loading: Boolean,
disabled: Boolean,
plain: Boolean,
autofocus: Boolean,
round: Boolean,
circle: Boolean
},
computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
buttonSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
buttonDisabled() {
return this.disabled || (this.elForm || {}).disabled;
}
},
methods: {
handleClick(evt) {
this.$emit('click', evt);
}
}
};
</script>
button的样式改变都是依靠传递设置不同的class来实现的。
接下来看样式文件(这里只截取一部分):
这里需要注意,源码中的样式文件为sass,我们测试对照的时候需要使用编译后的css文件。
以size为例:
当设置size='mini'后,el-button会为button元素添加一个名为:'el-button--mini'的class,对照样式文件可以看出,此时style会设置'font-size: 12px'。
其他样式也都与此类似,治至于disabled这类原本button就存在的属性,就只需要动态的传值即可。