A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

Layout(布局)源码分析
  • <el-row>源码分析
首先进入打开官网查看Layout相关部分的说明,发现主要的组件就2个: el-row,el-col,这2个分别代表行的容器和里面列的容器,类似于bootstrap的col和row,首先我们查看el-row的实现,进入package里面的row文件夹,里面是一个src文件夹和index.js文件

打开index.js,这里最后一句导出Row供我们import,而中间的install方法则是把这个组件当成一个Vue的插件来使用,通过Vue.use()来使用该组件,install方法传递一个Vue的构造器,Element的所有组件都是一个对象{...},里面有个render函数来创建组件的html结构,render方法的好处很大,使得创建html模板的代码更加简洁高效,而不是冗长的各种div标签堆叠,更类似于一种配置形式来创建html. 最后通过export default导出,而不是常用的单文件组件形式,因此必须提供install方法

import Row from './src/row';
/* istanbul ignore next */
Row.install = function(Vue) {
  //全局注册该组件(常用的组件最好全局注册)
  Vue.component(Row.name, Row);
};
export default Row;

下面进入src/row.js中一探究竟,首先代码的整体结构如下,直接导出一个对象,里面是组件的各种配置项


export default {
    ...
}
整个组件的代码量不多,下面是给出了详细注释
export default {
  //组件名称,注意是驼峰命名法,这使得实际使用组件时短横线连接法<el-row>和驼峰法<ElRow>都可以使用
  name: 'ElRow',
  //自定义属性(该属性不是component必需属性),重要,用于后面<el-col>不断向父级查找该组件
  componentName: 'ElRow',
  //组件的props
  props: {
    //组件渲染成html的实际标签,默认是div
    tag: {
      type: String,
      default: 'div'
    },
    //该组件的里面的<el-col>组件的间隔
    gutter: Number,
    /* 组件是否是flex布局,将 type 属性赋值为 'flex',可以启用 flex 布局,
    *  并可通过 justify 属性来指定 start, center, end, space-between, space-around
    *  其中的值来定义子元素的排版方式。
    */
    type: String,
    //flex布局的justify属性
    justify: {
      type: String,
      default: 'start'
    },
    //flex布局的align属性
    align: {
      type: String,
      default: 'top'
    }
  },


  computed: {
    //row的左右margin,用于抵消col的padding,后面详细解释,注意是计算属性,这里通过gutter计算出实际margin
    style() {
      const ret = {};
      if (this.gutter) {
        ret.marginLeft = `-${this.gutter / 2}px`;
        ret.marginRight = ret.marginLeft;
      }
      return ret;
    }
  },


  render(h) {
    //渲染函数,后面详细解释
    return h(this.tag, {
      class: [
        'el-row',
        this.justify !== 'start' ? `is-justify-${this.justify}` : '',
        this.align !== 'top' ? `is-align-${this.align}` : '',
        { 'el-row--flex': this.type === 'flex' }
      ],
      style: this.style
    }, this.$slots.default);
  }
};
下面说一下计算属性里面的sytle(),这里面通过gutter属性计算出了本组件的左右margin,且为负数,这里有点费解,下面上图解释,首先gutter的作用是让row里面的col产生出间隔来,但是注意容器的最左和最右侧是没有间隔的

上图就是最终示意图,黑框就是<el-row>的宽度范围,里面是<el-col>组件,下一节介绍, 这个组件的宽度其实按<el-row>百分比来计算,而且box-sizing是border-box,注意gutter属性是定义在父级的<el-row>上,子级的col通过$parent可以拿到该属性,然后给<el-col>分配padding-left和padding-right,因此每个col都有左右padding,上图中每个col占宽25%,gutter的宽度就是col的padding的2倍,但是注意最左侧和最右侧是没有padding的,那么问题来了,怎么消去最左和最右的padding? 这里就是<el-row>负的margin起的作用,如果不设置上面的计算属性的style,那么左右2侧就会有col的padding,因此这里负的margin抵消了col的padding,且该值为 -gutter/2+'px'
注意如果初看上面的图,一般的想法是col之间用margin来间隔,其实是不行的,而用padding来间隔就很简单,width按百分比来分配就行(box-sizing要设置为border-box)


点击有惊喜





0 个回复

您需要登录后才可以回帖 登录 | 加入黑马