实现一个栅格系统

704 阅读3分钟

如何实现一个自己的UI组件库

一开始,从简单的开始,我们从微信小程序开始,理解如何开始一个一个的组件。我们目的是一步步学习实践,然后具有构建UI组件库的能力,😝(小菜鸟大梦想~)

分析

我们先从别人的UI组件库中获取经验,第一个要看的就是 iviewLayout 组件,iview 的 UI 组件库实现了最简单 24 栅格系统。提供了如何的功能

  • 自定义 row 的样式 定会 i-class

  • span 自定义列数 col

  • col 自定义间隙 offset

  • 自定义 col 的样式 定会 i-class

我们能够获取到的经验就是:

  1. 栅格系统实现现在基本有两种:float + flex,两种布局方式
  2. 间隙的计算方式
  3. 组件传值问题

另外一些东西:

  1. gutter 在 iview 中是没有涉及的,但是我实现这个功能
  2. 在bootstrap和其他 UI 组件库中,都有断点媒体查询的功能,定不同的设备,但是以小程序为背景的就先没有必要涉及媒体查询,设置不同的栅格。

使用 float 实现 栅格系统

有浮动,我们就需要,清除浮动,我们先搞清除浮动的工具类,都知道是涨这样子的,但是你小程序写久了 flex 带来的爽快,容易然我们万户所以然。

.y-row:after{
    content:"";
    display:table;
    clear:both;
}

实现

小程序组件

<!--row-->
<view class="y-row gutter-{{gutter}}" 
      style="margin-right:{{-gutter/2}}px; margin-left: {{-gutter/2}}px">
  <slot></slot>
</view>
<!--col-->
<view class="col-{{span}} col-offset-{{offset}}" 
      style="padding-left: {{gutter/2}}px; padding-right: {{gutter/2}}px;">
  <slot></slot>
</view>
  1. 如何实现组件栅格的间隙 gutter?

间隙gutter的实现是使用使用左右padding的一半,和 box-sizing: border-box;但是会产生一个新的问题,就是第一个和最后一个也会有空余部分,我们解决办法是在row的组件里面使用负数gutter/2来解决开始和结尾的空白的问题。

  1. 如何实现组价位置的偏移offset?

offset使用margin-left实现

  1. 确定组件间关系!

微信小程序的组件关系的确定 child和parent,使用 relation 字段,即可在target字段里,拿到我们关联的字段!

// y-row
properties: {
    gutter: Number
  },
  data: {
    gutter: 0,
  },
  relations: {
    '../y-col/index': {
      type: 'child',
      linked: function (target) {
        let _this = this
        console.log("row-->col", target.data)
      },
    }
  }

// y-col
properties: {
    span: Number,
    offset: Number,
  },
  relations: {
    '../y-row/index': {
      type: 'parent',
      linked: function (target) {
        // 每次有custom-li被插入时执行,target是该节点实例对象,触发在该节点attached生命周期之后
        this.setData({
          gutter: target.data.gutter
        })
      },
    }
  }
  1. 栅格的最好使用css预处理器

使用scss预处理器

@charset 'UTF-8';

@for $grid from 1 to 25 {
    .col-#{$grid}{
      width: 100px * ($grid/24);
    }
}

基本使用方式

<y-row gutter="10">
  <y-col span="12">
    <view class="box blue"></view>
  </y-col>

  <y-col span="12">
    <view class="box yellow"></view>
  </y-col>
</y-row>

<y-row gutter="10">
  <y-col span="8">
    <view class="box blue"></view>
  </y-col>
</y-row>

<y-row gutter="10">
  <view>
    <y-col span="6">
    <view style="height: 20px; background: blue;"></view>
  </y-col>

  <y-col span="6">
    <view style="height: 20px; background: red;"></view>
  </y-col>

  <y-col span="6">
    <view style="height: 20px; background: blue;"></view>
  </y-col>

  <y-col span="6">
    <view style="height: 20px; background: yellow;"></view>
  </y-col>
  </view>
</y-row>

参考

  1. iview 小程序 UI 组件库