Layout布局
el-row
文件位置
- Element-ui>packages>row>src>row.js
- Element-ui>packages>theme-chalk>src>row.scss
Js代码
export default {
//组件的名字
name: 'ElRow',
//element-ui自定义的属性可以通过this.$options.componentName获得
componentName: 'ElRow',
props: {
tag: {
//自定义元素标签 默认为div标签 可以修改
type: String,
default: 'div'
},
//栅格间隔 px
gutter: Number,
//布局模式
type: String,
//flex 布局下的水平排列方式
justify: {
type: String,
default: 'start'
},
//flex 布局下的垂直排列方式
align: String
},
computed: {
style() {
const ret = {};
if (this.gutter) {
//左右设置一个-gutter/2的值 因为gutter在左右加上了padding-left和padding-right
// 这样会导致两边没有对齐父元素,所以加上负margin,对齐两侧
ret.marginLeft = `-${this.gutter / 2}px`;
ret.marginRight = ret.marginLeft;
}
return ret;
}
},
//通过渲染函数的形式编写
render(h) {
//第一个参数:标签
//第二个参数:配置 与模板中属性对应的数据对象
//第三个参数:子虚拟节点 插槽中的内容 写在el-row标签内部的部分
return h(this.tag, {
//class el-row is-justify-xx is-align-xx el-row--flex
class: [
'el-row',
this.justify !== 'start' ? `is-justify-${this.justify}` : '',
this.align ? `is-align-${this.align}` : '',
{ 'el-row--flex': this.type === 'flex' }
],
//上面的计算属性
style: this.style
}, this.$slots.default);
}
};
Row Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
gutter | 栅格间隔 | number | — | 0 |
type | 布局模式,可选 flex,现代浏览器下有效 | string | — | — |
justify | flex 布局下的水平排列方式 | string | start/end/center/space-around/space-between | start |
align | flex 布局下的垂直排列方式 | string | top/middle/bottom | — |
tag | 自定义元素标签 | string | * | div |
样式文件
@import "common/var";
@import "mixins/mixins";
@import "mixins/utils";
@include b(row) {
position: relative;
box-sizing: border-box;
@include utils-clearfix;
@include m(flex) {
display: flex;
&:before,
&:after {
display: none;
}
@include when(justify-center) {
justify-content: center;
}
@include when(justify-end) {
justify-content: flex-end;
}
@include when(justify-space-between) {
justify-content: space-between;
}
@include when(justify-space-around) {
justify-content: space-around;
}
@include when(align-top) {
align-items: flex-start;
}
@include when(align-middle) {
align-items: center;
}
@include when(align-bottom) {
align-items: flex-end;
}
}
}
@include b 混入了mixins/mixins中的b其中在config.scss定义了 BEM的Class命名风格
$namespace: 'el'; 组件名 el-row
$element-separator: '__'; 元素子元素 加上__ el-input__inner
$modifier-separator: '--'; 修饰符 el-button-primary
$state-prefix: 'is-'; 状态的前缀 is-disabled
mixins/mixins文件
@mixin b($block) {
定义变量
$B: $namespace+'-'+$block !global;
使用变量
.#{$B} {
@content;
}
}
@include utils-clearfix 混入utils.scss 中的utils-clearfix 清除浮动
@mixin utils-clearfix {
$selector: &;
@at-root {
#{$selector}::before,
#{$selector}::after {
display: table;
content: "";
}
#{$selector}::after {
clear: both
}
}
}
@include m 混入mixins中的m
@mixin m($modifier) {
$selector: &;
$currentSelector: "";
遍历修饰符 生成class名并拼接 el-row--flex
@each $unit in $modifier {
$currentSelector: #{$currentSelector + & + $modifier-separator + $unit + ","};
}
@at-root {
#{$currentSelector} {
@content;
}
}
}
@include when的混入,其实就是用来生成is-开头表示状态用的class
@mixin when($state) {
@at-root {
&.#{$state-prefix + $state} {
@content;
}
}
}
el-col
文件位置
- Element-ui>packages>row>src>col.js
- Element-ui>packages>theme-chalk>src>col.scss
js代码
export default {
name: 'ElCol',
props: {
//栅格占据的列数
span: {
type: Number,
default: 24
},
//可以自定义标签
tag: {
type: String,
default: 'div'
},
//栅格左侧的间隔格数
offset: Number,
//栅格向左移动格数
pull: Number,
//栅格向右移动格数
push: Number,
//响应式
xs: [Number, Object],
sm: [Number, Object],
md: [Number, Object],
lg: [Number, Object],
xl: [Number, Object]
},
computed: {
gutter() {
//获取父对象
let parent = this.$parent;
//一直向上寻找父对象 直到找到父对象名字为ElRow也就是el-row
while (parent && parent.$options.componentName !== 'ElRow') {
parent = parent.$parent;
}
//获取父对象上的gutter 栅格间隔
return parent ? parent.gutter : 0;
}
},
render(h) {
let classList = [];
let style = {};
//给左右两侧加上padding
if (this.gutter) {
style.paddingLeft = this.gutter / 2 + 'px';
style.paddingRight = style.paddingLeft;
}
//遍历span offset pull push设置 并加上对应的类名
['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]}`
);
}
});
//对应响应式同样加上类名
['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);
}
};
Col Attributes
参数 | 说明 | 类型 | 可选值 | 默认值 |
---|---|---|---|---|
span | 栅格占据的列数 | number | — | 24 |
offset | 栅格左侧的间隔格数 | number | — | 0 |
push | 栅格向右移动格数 | number | — | 0 |
pull | 栅格向左移动格数 | number | — | 0 |
xs | <768px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
sm | ≥768px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
md | ≥992px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
lg | ≥1200px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
xl | ≥1920px 响应式栅格数或者栅格属性对象 | number/object (例如: {span: 4, offset: 4}) | — | — |
tag | 自定义元素标签 | string | * | div |
样式文件
@import "./common/var.scss";
@import "./mixins/mixins.scss";
每一个el-col开头的元素设置了左浮动和border-box属性
[class*="el-col-"] {
float: left;
box-sizing: border-box;
}
.el-col-0 {
display: none;
}
循环从0-24设置span、offset、pull、push的样式
@for $i from 0 through 24 {
.el-col-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
@include res(xs) {
.el-col-xs-0 {
display: none;
}
@for $i from 0 through 24 {
.el-col-xs-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-xs-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-xs-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-xs-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
}
@include res(sm) {
.el-col-sm-0 {
display: none;
}
@for $i from 0 through 24 {
.el-col-sm-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-sm-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-sm-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-sm-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
}
@include res(md) {
.el-col-md-0 {
display: none;
}
@for $i from 0 through 24 {
.el-col-md-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-md-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-md-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-md-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
}
@include res(lg) {
.el-col-lg-0 {
display: none;
}
@for $i from 0 through 24 {
.el-col-lg-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-lg-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-lg-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-lg-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
}
@include res(xl) {
.el-col-xl-0 {
display: none;
}
@for $i from 0 through 24 {
.el-col-xl-#{$i} {
width: (1 / 24 * $i * 100) * 1%;
}
.el-col-xl-offset-#{$i} {
margin-left: (1 / 24 * $i * 100) * 1%;
}
.el-col-xl-pull-#{$i} {
position: relative;
right: (1 / 24 * $i * 100) * 1%;
}
.el-col-xl-push-#{$i} {
position: relative;
left: (1 / 24 * $i * 100) * 1%;
}
}
}
res的混入接收两个参数,$key表示传入响应式的key值(xs、sm等)
/* Break-points
-------------------------- */
@mixin res($key, $map: $--breakpoints) {
// 循环断点Map,如果存在则返回
@if map-has-key($map, $key) {
@media only screen and #{inspect(map-get($map, $key))} {
@content;
}
} @else {
@warn "Undefeined points: `#{$map}`";
}
}
如果没有传入第二个参数map ,会使用默认值 map,会使用默认值map,会使用默认值–breakpoints
/* Break-point
--------------------------*/
$--sm: 768px !default;
$--md: 992px !default;
$--lg: 1200px !default;
$--xl: 1920px !default;
$--breakpoints: (
'xs' : (max-width: $--sm - 1),
'sm' : (min-width: $--sm),
'md' : (min-width: $--md),
'lg' : (min-width: $--lg),
'xl' : (min-width: $--xl)
);