上一章咱们说到哪了,md-loader那是十分了得,将markdown语法搞得是方便简洁,灵活多便。
我们接着上一章继续道来,咱们细说element-ui组件
布局
作为本章的开场组件el-row和el-col,他们的作用主要是对块进行分割排布
我来说说具体是怎么实现的
Row
Row组件是通过render函数来渲染
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);
栅格间距gutter:通过计算属性定义了一个style属性,返回左右外边距为负gutterpx的对象,这样div的整体宽度就为width+gutter * 2,Col也是均分着额外的gutter
包裹标签tag:从上面的代码也能看出它是用来定义Row组件最外层标签类型的
type:是否定义为flex
justify:定义相关的class,来进行flex横轴布局
align:定义相关的class,来进行flex纵轴布局
Col
Col组件是通过render函数来渲染,这个布局组件好多样式都是通过class定义的,通过vue的$parent获取到外层Row组件的gutter,以gutterpx为Col最外层标签的左右内边距
if (this.gutter) {
style.paddingLeft = this.gutter / 2 + 'px';
style.paddingRight = style.paddingLeft;
}
栅格占据的列数span,栅格左侧的间隔格数offset,栅格向右移动格数push,栅格向左移动格数pull被定义到数组,通过遍历以class属性添加到Col最外层标签上
['span', 'offset', 'pull', 'push'].forEach(prop => {
if (this[prop] || this[prop] === 0) {
classList.push(
prop !== 'span'
? `el-col-${prop}-${this[prop]}`
: `el-col-${this[prop]}`
);
}
});
<768px xs,≥768px sm,≥992px md,≥1200px lg,≥1920px xl首先判断是不是数值,如果不是数值走另一套生成class的规则,最后根据props和Row的gutter属性,生成相应的dom返回
['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
if (typeof this[size] === 'number') {
classList.push(`el-col-${size}-${this[size]}`);
} else if (typeof this[size] === 'object') {
let props = this[size];
Object.keys(props).forEach(prop => {
classList.push(
prop !== 'span'
? `el-col-${size}-${prop}-${props[prop]}`
: `el-col-${size}-${props[prop]}`
);
});
}
});
return h(this.tag, {
class: ['el-col', classList],
style
}, this.$slots.default);
容器
容器的制作非常简单,简单到我不想单独讲
Container
根据父组件传过来的direction和默认插槽中的组件是否有Header或Footer,来决定是否将标签<section>用flex的基准线改为y轴
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;
}
Header,Main,Aside,Footer
其他组件没有太多的东西,应该主要是为了语义化,使用了<header>,<main>,<aside>,<footer>标签,通过父组件传入的height,width决定它的整体大小