布局组件中的父组件,用于控制子组件。很简单的一个布局标签,主要经过 justify 和 align 控制子元素的对齐方式,使用 render 函数经过传入的 tag 属性控制生成的标签。html
在这里推荐学习下 render 函数和 JSX 的写法,由于以后比较复杂的组件都是经过 render函数 + JSX 的方式来写的。vue
// 核心代码
render(h) {
return h(this.tag, {
class: [
'el-row',
this.justify !== 'start' ? `is-justify-${this.justify}` : '',
this.align !== 'top' ? `is-align-${this.align}` : '',
{ 'el-row--flex': this.type === 'flex' }
],
style: this.style
}, this.$slots.default);
}
复制代码
布局组件中的子组件,经过传入的props控制占据的列数、偏移、大小等,经过 forEach 对每一个属性进行处理,生成包含对应样式的 classList。node
最后将 classList 传入 createElement 函数(h)中的第二个参数(标签选项)中,如此,就生成了所须要的布局。ide
// 核心代码
render (h) {
// 省略,经过props计算classList
return h(this.tag, {
class: ['el-col', classList],
style
}, this.$slots.default);
}
复制代码
父容器组件,根据传入的direction字段,决定样式是水平仍是垂直。当没有传入direction字段时,根据插槽中子组件是否含有 header 或 footer组件,若是含有则为垂直,不然为水平。函数
// 核心代码
computed: {
isVertical() {
if (this.direction === 'vertical') {
return true;
} else if (this.direction === 'horizontal') {
return false;
}
return this.$slots && this.$slots.default
? this.$slots.default.some(vnode => {
const tag = vnode.componentOptions && vnode.componentOptions.tag;
return tag === 'el-header' || tag === 'el-footer';
})
: false;
}
}
复制代码
最简单的组件之一,经过传入的 height 参数定义 style 高度。布局
最简单的组件之一,经过传入的 width 参数控制 style 宽度。学习
真正意义上的最简单容器组件,包含插槽的纯容器。flex
最简单的组件之一,经过传入的 height 参数定义 style 高度。this
何为容器?在个人理解中,容器就是一个限制大小的盒子。布局容器经过属性定义 header、aside、footer 的高宽的行内样式,接下来只须要定义 main 为 flex: 1 便可实现自适应布局。spa
感受比较没有意义的一个组件,经过传入的 name 来组成相似于 el-icon-name
格式的类,而后将这个类定义在 i 标签内。不过大多数人都不会用这个组件,为何?由于连官网推荐写法都是直接在 i 标签内添加对应图标的类。
Button 组件是 Basic 里面惟一一个稍微复杂一点的组件。它与其余 Basic 组件的最大区别在于,经过 provide/inject 获取了祖先组件,而后参照祖先组件的尺寸参数,将 Button 组件的尺寸参数设为一致。
Button 组件的尺寸由三个因素决定:
this.$ELEMENT
对象中的 size 属性决定。What? this.$ELEMENT
什么鬼?它是接收初始化 ElementUI 时传入的尺寸参数的对象,包含两个属性:size 以及 zIndex,方便全局定义各类组件的尺寸。类比于样式中的 body 样式继承。// 核心代码
export default {
name: 'ElButton',
// 经过 inject 获取 elForm 以及 elFormItem 这两个组件
inject: {
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
// ...
computed: {
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
buttonSize() {
// 三种因素决定按钮的尺寸
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
//...
},
// ...
};
复制代码
和通常文字连接区别不大的一个组件,主要区别在于两点:
值得一提的是,该组件还使用了一个通用组件开发的小技巧:经过 v-bind="$attrs"
进行快速属性赋值。为何要这样作?由于 a 标签能够含有各类 html 属性,而这些属性咱们不可能一一经过 props 接收而后赋值到 a 标签的属性上。
所以,咱们能够经过 v-bind="$attrs"
无视传入的属性是什么,一股脑将其赋值到 a 标签上。这至关于,开发者能够直接像操做 a 标签同样操做 Link 组件,大大方便了组件的使用。
<template>
<a
:class="[
'el-link',
type ? `el-link--${type}` : '',
disabled && 'is-disabled',
underline && !disabled && 'is-underline'
]"
:href="disabled ? null : href"
v-bind="$attrs"
@click="handleClick"
>
<i :class="icon" v-if="icon"></i>
<span v-if="$slots.default" class="el-link--inner">
<slot></slot>
</span>
<template v-if="$slots.icon"><slot v-if="$slots.icon" name="icon"></slot></template>
</a>
</template>
复制代码
通读了 Basic 系列的源码,能够发现,这一部分的源码其实相对比较简单,可是,却又不少的小细节点值得学习,好比:经过 v-bind=$attrs
定义标签属性、经过组合插槽方便组件使用、经过多种因素设定属性以及各类缺省设计等等。