ElementUI
源码学习 - Button
button.vue
<template>
<button
class="el-button"
@click="handleClick" //向父级传递事件
:disabled="buttonDisabled || loading" //当disabled 和 loading 状态下,都无法点击
:autofocus="autofocus" // 自动focus
:type="nativeType" // 支持原生事件
:class="[ //动态绑定 calss 数组包含 对象
type ? 'el-button--' + type : '', //btn 样式
buttonSize ? 'el-button--' + buttonSize : '', // btn 大小
{
'is-disabled': buttonDisabled, //以下都是控制样式
'is-loading': loading,
'is-plain': plain,
'is-round': round,
'is-circle': circle
}
]"
>
<i class="el-icon-loading" v-if="loading"></i> // loading icon 效果
<i :class="icon" v-if="icon && !loading"></i> // 当loading 时候,不显示其他icon
<span v-if="$slots.default"><slot></slot></span>
// $slots.default 默认插槽 当默认插槽有值才会显示
// 用$slots.default来判断是否有子元素存在,可以借鉴
</button>
</template>
<script>
export default {
name: 'ElButton',
//name 作用
// 限制:只有作为组件选项时起作用。
// 1.允许组件模板递归地调用自身。
// 2.便于调试,有名字的组件有更友好的警告信息。在有 vue-devtools,通过提供 name 选项,可以获得更有语义信息的组件树。
// 3.当项目使用keep-alive时,可搭配组件name进行缓存过滤
inject: {
// 需要和 provide 一同使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,
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
几个重要样式
1.
display:inline-block
,表明按钮内联块状分布,一行可以有多个排列,且可以控制宽高2.
-webkit-appearence:none
表示将按钮原生的样式去掉,首先是太丑其实不同浏览器表现不同3.按钮是没有设置宽高的,根据内容以及
padding
撑开的4.
line-height:1
表示行高和字体大小一样,要是为2则是为字体的2倍大
button-group.vue
<template>
<div class="el-button-group">
<slot></slot> //插槽
</div>
</template>
<script>
export default {
name: 'ElButtonGroup'
};
</script>
注意
el-button-group
的内容是display:inline-block
,也就说明这个wrapper其实也是内联块状的表现,里面的slot承载子button
button-group
样式
<style >
.el-button-group > .el-button:first-child {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.el-button-group>.el-button:last-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.el-button-group.el-button--primary:not(:first-child):not(:last-child) {
border-left-color: hsla(0,0%,100%,.5);
border-right-color: hsla(0,0%,100%,.5);
}
</style>
first-child
第一个子元素 右边上下圆角为0
last-child
最后一个元素 左边上下圆角为0
not(:first-child):not(:last-child)
不是第一个也不是最后一个 中间空隙用border
来隔开
index.js
import ElButton from './src/button';
/* istanbul ignore next */
/* Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:*/
ElButton.install = function(Vue) {
Vue.component(ElButton.name, ElButton);
};
export default ElButton; //导出
引入组件的方式
// 方法一:
name
是组件的名字
Vue.component(Button.name, Button)
// 方法二:前提是Button
有提供install
这个方法
Vue.use(Button)
上面两种方式都可以用来全局注册组件,但是参数不一样,选择哪种方法都可以,但要留意一下第二种方法,这种方法需要组件本身有个
install
的方法。