Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ts-element系列之布局 #5

Open
webVueBlog opened this issue Aug 15, 2022 · 0 comments
Open

ts-element系列之布局 #5

webVueBlog opened this issue Aug 15, 2022 · 0 comments

Comments

@webVueBlog
Copy link
Owner

Vue 的模板最终会编译成 render 函数,Vue 的组件也支持直接手写 render 函数

h 是 Vue 内部实现的 $createElement 函数

设置不同的宽度百分比只需要设置不同的 CSS

为了满足 24 种情况,element-ui 使用了 sass 的控制指令,配合基本的计算公式:

.el-col-0 {
  display: none;
}

@for $i from 0 through 24 {
  .el-col-#{$i} {
    width: (1 / 24 * $i * 100) * 1%;
  }
}
render(h) {
  let classList = [];
  classList.push(`el-col-${this.span}`);
  
  return h(this.tag, {
    class: [
      'el-col',
       classList
    ]
  }, this.$slots.default);
}

这样只要指定 span 属性的列就会添加 el-col-${span} 的样式,实现了分栏布局的需求。

provide() {
  return {
    row: this
  };
}

inject: ['row']

对于不同偏移的分栏数,会有对应的 margin 百分比,就很好地实现分栏偏移需求。

利用 flex 布局来对分栏做灵活的对齐。

element-ui 的自定义 @mixin 定义在 pacakages/theme-chalk/src/mixins/ 目录中

mixins/config.scss 中定义了一些全局变量:

$namespace: 'el';
$element-separator: '__';
$modifier-separator: '--';
$state-prefix: 'is-';

响应式布局

element-ui 参照了 Bootstrap 的响应式设计,预设了五个响应尺寸:xs、sm、md、lg 和 xl。

<el-row type="flex" justify="center">
  <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">aaa</el-col>
  <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">bbb</el-col>
  <el-col :xs="4" :sm="6" :md="8" :lg="9" :xl="11">ccc</el-col>
  <el-col :xs="8" :sm="6" :md="4" :lg="3" :xl="1">ddd</el-col>
</el-row>
<el-row>
  ...
</el-row>

传入的 props 去生成对应的 CSS,在 CSS 中利用媒体查询去实现响应式。

render(h) {
  let classList = [];
  classList.push(`el-col-${this.span}`);
  classList.push(`el-col-offset-${this.offset}`);
  
   ['xs', 'sm', 'md', 'lg', 'xl'].forEach(size => {
     classList.push(`el-col-${size}-${this[size]}`); 
   });
  
  let style = {};
  
  if (this.gutter) {
    style.paddingLeft = this.gutter / 2 + 'px';
    style.paddingRight = style.paddingLeft;
  }
  
  return h(this.tag, {
    class: [
      'el-col',
       classList
    ]
  }, this.$slots.default);
}
@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 参数的默认值是 $--breakpoints,定义在 pacakges/theme-chalk/src/common/var.scss 中:

$--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)
);
@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%;
    }
  }
}
@media only screen and (max-width: 767px) {
  .el-col-xs-0 {
    display: none;
  }
  .el-col-xs-1 {
    width: 4.16667%
  }
  .el-col-xs-offset-1 {
    margin-left: 4.16667%
  }
  // 后面循环的结果太长,就不贴了
}
$--breakpoints-spec: (
  'xs-only' : (max-width: $--sm - 1),
  'sm-and-up' : (min-width: $--sm),
  'sm-only': "(min-width: #{$--sm}) and (max-width: #{$--md - 1})",
  'sm-and-down': (max-width: $--md - 1),
  'md-and-up' : (min-width: $--md),
  'md-only': "(min-width: #{$--md}) and (max-width: #{$--lg - 1})",
  'md-and-down': (max-width: $--lg - 1),
  'lg-and-up' : (min-width: $--lg),
  'lg-only': "(min-width: #{$--lg}) and (max-width: #{$--xl - 1})",
  'lg-and-down': (max-width: $--xl - 1),
  'xl-only' : (min-width: $--xl),
);
.hidden-xs-only {
  @media only screen and (max-width:767px) {
    display: none !important;
  }
}

利用媒体查询定义了这些 CSS 规则,实现了在某些屏幕尺寸下隐藏的功能。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant