如何实现一个自己的UI组件库
一开始,从简单的开始,我们从微信小程序开始,理解如何开始一个一个的组件。我们目的是一步步学习实践,然后具有构建UI组件库的能力,😝(小菜鸟大梦想~)
分析
我们先从别人的UI组件库中获取经验,第一个要看的就是 iview
的 Layout
组件,iview 的 UI 组件库实现了最简单 24 栅格系统。提供了如何的功能
-
自定义 row 的样式 定会 i-class
-
span 自定义列数 col
-
col 自定义间隙 offset
-
自定义 col 的样式 定会 i-class
我们能够获取到的经验就是:
- 栅格系统实现现在基本有两种:float + flex,两种布局方式
- 间隙的计算方式
- 组件传值问题
另外一些东西:
- gutter 在 iview 中是没有涉及的,但是我实现这个功能
- 在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>
- 如何实现组件栅格的间隙 gutter?
间隙gutter的实现是使用使用左右padding的一半,和 box-sizing: border-box
;但是会产生一个新的问题,就是第一个和最后一个也会有空余部分,我们解决办法是在row的组件里面使用负数gutter/2来解决开始和结尾的空白的问题。
- 如何实现组价位置的偏移offset?
offset使用margin-left实现
- 确定组件间关系!
微信小程序的组件关系的确定 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
})
},
}
}
- 栅格的最好使用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>