Layout(布局)源码分析首先进入打开官网查看Layout相关部分的说明,发现主要的组件就2个: el-row,el-col,这2个分别代表行的容器和里面列的容器,类似于bootstrap的col和row,首先我们查看el-row的实现,进入package里面的row文件夹,里面是一个src文件夹和index.js文件
打开index.js,这里最后一句导出Row供我们import,而中间的install方法则是把这个组件当成一个Vue的插件来使用,通过Vue.use()来使用该组件,install方法传递一个Vue的构造器,Element的所有组件都是一个对象{...},里面有个render函数来创建组件的html结构,render方法的好处很大,使得创建html模板的代码更加简洁高效,而不是冗长的各种div标签堆叠,更类似于一种配置形式来创建html. 最后通过export default导出,而不是常用的单文件组件形式,因此必须提供install方法
import Row from './src/row';
/* istanbul ignore next */
Row.install = function(Vue) {
//全局注册该组件(常用的组件最好全局注册)
Vue.component(Row.name, Row);
};
export default Row;
下面进入src/row.js中一探究竟,首先代码的整体结构如下,直接导出一个对象,里面是组件的各种配置项
export default {
...
}
整个组件的代码量不多,下面是给出了详细注释
export default {
//组件名称,注意是驼峰命名法,这使得实际使用组件时短横线连接法<el-row>和驼峰法<ElRow>都可以使用
name: 'ElRow',
//自定义属性(该属性不是component必需属性),重要,用于后面<el-col>不断向父级查找该组件
componentName: 'ElRow',
//组件的props
props: {
//组件渲染成html的实际标签,默认是div
tag: {
type: String,
default: 'div'
},
//该组件的里面的<el-col>组件的间隔
gutter: Number,
/* 组件是否是flex布局,将 type 属性赋值为 'flex',可以启用 flex 布局,
* 并可通过 justify 属性来指定 start, center, end, space-between, space-around
* 其中的值来定义子元素的排版方式。
*/
type: String,
//flex布局的justify属性
justify: {
type: String,
default: 'start'
},
//flex布局的align属性
align: {
type: String,
default: 'top'
}
},
computed: {
//row的左右margin,用于抵消col的padding,后面详细解释,注意是计算属性,这里通过gutter计算出实际margin
style() {
const ret = {};
if (this.gutter) {
ret.marginLeft = `-${this.gutter / 2}px`;
ret.marginRight = ret.marginLeft;
}
return ret;
}
},
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);
}
};
下面说一下计算属性里面的sytle(),这里面通过gutter属性计算出了本组件的左右margin,且为负数,这里有点费解,下面上图解释,首先gutter的作用是让row里面的col产生出间隔来,但是注意容器的最左和最右侧是没有间隔的
上图就是最终示意图,黑框就是<el-row>的宽度范围,里面是<el-col>组件,下一节介绍, 这个组件的宽度其实按<el-row>百分比来计算,而且box-sizing是border-box,注意gutter属性是定义在父级的<el-row>上,子级的col通过$parent可以拿到该属性,然后给<el-col>分配padding-left和padding-right,因此每个col都有左右padding,上图中每个col占宽25%,gutter的宽度就是col的padding的2倍,但是注意最左侧和最右侧是没有padding的,那么问题来了,怎么消去最左和最右的padding? 这里就是<el-row>负的margin起的作用,如果不设置上面的计算属性的style,那么左右2侧就会有col的padding,因此这里负的margin抵消了col的padding,且该值为 -gutter/2+'px'
注意如果初看上面的图,一般的想法是col之间用margin来间隔,其实是不行的,而用padding来间隔就很简单,width按百分比来分配就行(box-sizing要设置为border-box)
点击有惊喜
|
|