当前位置:   article > 正文

Element-UI源码——Layout布局_element layout布局

element layout布局

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);
  }
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

Row Attributes

参数说明类型可选值默认值
gutter栅格间隔number0
type布局模式,可选 flex,现代浏览器下有效string
justifyflex 布局下的水平排列方式stringstart/end/center/space-around/space-betweenstart
alignflex 布局下的垂直排列方式stringtop/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;
    }
  }

}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

@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
  • 1
  • 2
  • 3
  • 4
mixins/mixins文件
@mixin b($block) {
  定义变量
  $B: $namespace+'-'+$block !global;
	使用变量
  .#{$B} {
    @content;
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

@include utils-clearfix 混入utils.scss 中的utils-clearfix 清除浮动

@mixin utils-clearfix {
  $selector: &;

  @at-root {
    #{$selector}::before,
    #{$selector}::after {
      display: table;
      content: "";
    }
    #{$selector}::after {
      clear: both
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

@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;
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

@include when的混入,其实就是用来生成is-开头表示状态用的class

@mixin when($state) {
  @at-root {
    &.#{$state-prefix + $state} {
      @content;
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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);
  }
};

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

Col Attributes

参数说明类型可选值默认值
span栅格占据的列数number24
offset栅格左侧的间隔格数number0
push栅格向右移动格数number0
pull栅格向左移动格数number0
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%;
    }
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156

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}`";
  }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

如果没有传入第二个参数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)
);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/正经夜光杯/article/detail/959453
推荐阅读
相关标签
  

闽ICP备14008679号