珊格化组件的实现

303 阅读2分钟

这是我参与8月更文挑战的第1天,活动详情查看:8月更文挑战

背景:

笔者下班的时间自己在写vue相关的技术书籍,写到组件部分的时候,和读者介绍了珊格组件,书中的主要内容就是介绍珊格组件的使用场景,因为说的是element-ui珊格组件,介绍珊格组件的同时,介绍了一些API用法,总之整体的内容是停留在使用的层面,没有进一步的揭示珊格组件的实现原理,在在此基础上实现一个,所以写本文的目的,笔者就是想实现一个珊格组件。

珊格组件简介:

有之前使用过bootstrap的同学会知道, bootstrap也是有珊格布局的, Bootstrap 提供了一套“响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列”。element-ui 在此基础上,分成了24列。

element-ui珊格组件是按照行(row)和列(column)的形式对页面进行布局,举个例子,在一行中,三等分该行的方法是使用:

<el-row>
 <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
 <el-col :span="8"><div class="grid-content bg-purple-light"></div></el-col>
 <el-col :span="8"><div class="grid-content bg-purple"></div></el-col>
</el-row>

span的间距是8,因为一行是24等份,所以这里就实现了三等分。珊格组件使用起来是非常简单的,除了最基本的用法之外,珊格组件还有很多的API,包括gutter,flex等等,相关的用法读者参考element-ui的文档即可,这里就不再多多描述了。

珊格组件的用法就介绍到这里了,后面的内容笔者就主要讲述珊格组件是这么实现的了,这个阶段,读者可以先自己看看element-ui 文档,写几个demo体验一下珊格组件的用法。

element-ui珊格化组件的实现思路分析:

因为珊格化组件是通过row 和 column实现的 ,所以分析代码的时候,也是从这两个方面去分析代码;

  • row:

row.js 定义了row组件,row是行元素,支持gutter,在设计上gutter作为props属性传入组件:

  computed: {
    style() {
      const ret = {};

      if (this.gutter) {
        ret.marginLeft = `-${this.gutter / 2}px`;
        ret.marginRight = ret.marginLeft;
      }

      return ret;
    }
  }

ret 对象作为style最后传入渲染函数中。 注意一点,row 其实是个语法糖,在element-ui中默认使用div作为容器,此时row呈现的就是div;

row支持的属性在props中定义:

  props: {
    tag: {
      type: String,
      default: 'div'
    },
    gutter: Number,
    type: String,
    justify: {
      type: String,
      default: 'start'
    },
    align: String
  },
  • column:

column是列元素 ,列元素是有span属性的,在column内部定义单位xs , sm , md , lg, xl 作为预定的间距,间距和css属性关联,最终显示出不同间距的效果。

这一部分的逻辑实现的关键代码:

    ['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]}`
          );
        });
      }
    }

上述预定的参数作为props传递:

props:{
    xs: [Number, Object],
    sm: [Number, Object],
    md: [Number, Object],
    lg: [Number, Object],
    xl: [Number, Object]
} 

总结:

row 和 column组件布局部分差不多就介绍完成了,本来这篇文章要在上周写完的,但是一拖再拖,今晚笔者刚打完球,回来直接把它写了。笔者最近在公司做的工作是和组件有关的,所以最近的文章基本上是组件的内容。

about me: 两年前端小奶,WeChat:Yingbin192 ,兼职剧本杀dm , 欢迎和我交流,剧本可以,技术也可以~