超详细 ElementUI 源码分析 —— Layout

Layout 是用来快速布局的组件,本质上是和 Bootstrap 的栅格系统(真的很牛批,建议看一下它的源码)同样,将每一行分红 24 个小块,每个小块就是一列,经过指定合并的列数来建立布局,本文就 ElementUI 的 Layout 布局进行了分析。html

Layout 布局

首先咱们来分析一下问什么要使用 Layout?vue

  • 咱们在写原生 HTML 甚至是在使用 Vue 模板时,会使用div对每一个模块进行分割,可是通篇的div会使咱们的代码语义不清,H5 就要求咱们使用标签语义化,但即使是使用了标签语义化,有一些地方仍是会显得模糊不清,并且在样式上也难以维护。
  • 对于简单的布局咱们不但愿每次都须要本身来写,若是有一个模板快速帮咱们实现布局就行了。

基于以上理由,Layout 就出现了,它能作什么?git

  • 快速布局
  • 响应式布局

这里就不说使用了,具体使用请参考官方文档github

Layout 布局分为两个组件:row 和 colide

参数

关于 row 的参数请参考函数

col 参数请参考源码分析

间隔

关于 row 组件最重要的部分就是栅格间隔gutter,也就是每个分栏之间的距离,看源码:布局

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

    // 若是传入了 gutter
    if (this.gutter) {
      // 向左移动间隔的一半
      ret.marginLeft = `-${this.gutter / 2}px`
      // 向右移动间隔的一半
      ret.marginRight = ret.marginLeft
      // 
    }

    return ret
  }
}
复制代码

首先gutter是由每一列自身的padding产生的,在col.js中能够看出来,paddinggutter的一半。假如间隔为 20px,列的padding:0 10px,因此两列之间就产生了 20px 的间隔,这个很好理解。post

那么row.js中为何要给 row 组件添加一个margin呢,熟悉 Bootstrap 的小伙伴应该知道,这是考虑了在「列中嵌套行」的状况,若是在行中不加margin就会致使有某些列的间隔大于预期,好比说下面的代码结构flex

<el-row :gutter="20" type="flex" justify="end">
  <el-col :span="6">
    <el-row :gutter="10">
      <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
      <el-col :span="12"><div class="grid-content bg-purple"></div></el-col>
    </el-row>
  </el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
  <el-col :span="6"><div class="grid-content bg-purple"></div></el-col>
</el-row>
复制代码

在第一列中嵌套了一行,这一行里又有两列,看渲染出来的效果图:

能够看出来,外面的大间隔为 20px,第一列的小间隔为 10px,如今把margin去了看一下对比:

能够明显发现第一大列的左右都增长了 5px,这样就破坏了原有的gutter值,使得布局不符合预期,这就是margin的精妙之处。

渲染函数

而后咱们看一下渲染函数。

移步官网查看渲染函数的详细介绍

// 渲染函数
render (h) {
  return h(
    // 默认渲染的是一个 div
    this.tag,
    {
      // 至关于模板中的 :class
      class: [
        'el-row',
        // 若是 flex 布局不是默认的值,就会加上 .is-justify-
        // 就是加上了 justify-content: flex-end
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        // 若是开启了 flex 布局模式,则会加上 .el-row--flex
        // 就是加上了 display: flex
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    },
    // 子集虚拟节点
    this.$slots.default
  )
}
复制代码

咱们注意到 row 组件 和 col 组件中没有提供模板,而是使用渲染函数来建立的 HTML 结构,这样作能让咱们更好的处理细节。

关于col.js里面的东西主要是为了添加组件的样式,经过父组件传递的属性动态添加 class,Layout 布局主要部分也就是 CSS 了,因此本文先不详述了,后期会单独分析样式文件,感兴趣的能够先关注一波。源码全部的解释在个人Github里,欢迎进来点个 star。

传送门

【2020.3.15】超详细 ElementUI 源码分析 —— Layout

相关文章
相关标签/搜索