正文
距离第一篇UI组件库文章发布已经过去3个月了,在此期间利用零零散散的时间持续更新owl-ui组件库,目前owl-ui移动端组件库已经更新3大类(基础、表单、弹出层)9种组件(Button、Tabs、Input、Select、Switch、Drawer、Dialog、Picker、Toast)供使用。本篇文章主要讲述我在这3个月内开发UI组件的个人心得。如果想了解项目结构可以阅读上一篇文章,如果想了解实现原理可以阅读源码。所有连接在文章的结尾处。
我们从弹出层组件讲起
前方多图预警
先看效果图。
我在选择写组件的时候,首先选择做弹出层部分。为什么呢?我列出以下几点。
- 共性高、可复用。
- 兼容性高。
- 快速出货,提升成就感。
先说第一点:共性高、可复用
因为本人非常笨,所以做事之前需要构思很久,这样会减少之后重复性的工作。比如在做弹出层的时候,不少人会发现以上组件的共同点。没错,他们都是显示或隐藏(废话)。我们接着往下分析,除了显示或隐藏之外,他们大部分都有遮罩层部分。还有动画效果也一致。我们先根据这几点把功能抽象出来,如何做呢?
在vue和less中都有mixins方式,根据mixins我们很方便的将组件中的共性提取出来,达到代码精简的目的。以下代码就是弹出层组件中显示或隐藏功能的mixins文件。
// src/common/mixins/visibility.js
const EVENT_TOGGLE = 'toggle'
export default {
model: {
prop: 'visible',
event: EVENT_TOGGLE
},
props: {
visible: {
type: Boolean,
default: false
},
zIndex: {
type: Number,
default: 100
},
maskStyle: {
type: Object,
default: () => {}
},
containerStyle: {
type: Object,
default: () => {}
}
},
data () {
return {
isVisible: false
}
},
methods: {
hide () {
this.isVisible = false
},
show () {
this.isVisible = true
}
},
watch: {
isVisible (val) {
this.$emit('update:visible', val)
this.$emit('callback', val)
if (this.lockScroll) {
document.body.style.overflow = val ? 'hidden' : ''
}
},
visible: {
handler (val) {
this.isVisible = val
}
}
},
beforeDestroy () {
this.lockScroll && (document.body.style.overflow = '')
}
}
复制代码
上面主要做一件事,根据visible属性判断组件展示或隐藏。
使用方式如下:
// 组件文件
复制代码
顺便说一下项目中运用到less的mixins运用,比如1px问题。
// src/styles/common/border.less
.min-device-pixel-ratio(@scale2, @scale3) {
@media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
transform: @scale2;
}
@media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
transform: @scale3;
}
}
.border-1px(@color: #DDD, @radius: 2PX, @style: solid) {
&::before {
content: "";
pointer-events: none;
display: block;
position: absolute;
left: 0;
top: 0;
transform-origin: 0 0;
border: 1PX @style @color;
border-radius: @radius;
box-sizing: border-box;
width: 100%;
height: 100%;
@media screen and (min-device-pixel-ratio: 2), (-webkit-min-device-pixel-ratio: 2) {
width: 200%;
height: 200%;
border-radius: @radius * 2;
transform: scale(.5);
}
@media screen and (min-device-pixel-ratio: 3), (-webkit-min-device-pixel-ratio: 3) {
width: 300%;
height: 300%;
border-radius: @radius * 3;
transform: scale(.33);
}
}
}
.border-top-1px(@color: #DDD, @style: solid) {
&::before {
content: "";
position: absolute;
left: 0;
top: 0;
width: 100%;
border-top: 1Px @style @color;
transform-origin: 0 0;
.min-device-pixel-ratio(scaleY(.5), scaleY(.33));
}
}
复制代码
该函数可以通过传参改变线的颜色和类型。
使用方式如下:
// src/styles/packages/dialog.less
@import "../common/border";
@dialog-prefix-cls: ~"@{css-prefix}dialog";
.@{dialog-prefix-cls} {
...
&-btns {
...
.border-top-1px(); // Here
}
}
复制代码
合理的运用mixins可以使得项目结构清晰、减少冗余代码更利于后期维护。
优化方式有很多种,每个人有不同的编码习惯,因人而异。但是目标都是一致的,让自己的代码变得简洁、精炼和易读。
在弹出层中将公共部分抽象封装,比如遮罩层
// src/common/components/popup-mask.vue
"popup-mask"
:style="{ ...maskStyle, zIndex: zIndex - 1 }"
@click.stop.prevent="handleMask">
复制代码
第二点:兼容性高
我在工作中接触的移动端需求比较多,PC端做过一些管理后台。移动端与PC端的项目,给我最最直观的感受是,移动端要求UI极其严格,一像素都不能差,而PC端差不多就可以了,UI设计师们也不会过多纠结PC端做出来的页面是否跟原型图完全吻合。
在移动端,有的产品特别喜欢更改UI设计,特别是有表单部分的页面,今天产品嫌弃字体小了,明天可能觉得字体又太大了;今天把输入框改成圆角,明天就喜欢直角。今天觉得横向布局好,没准明天就要试试纵向布局。产品觉得这么改不要紧,殊不知如果项目中运用了UI组件库,这么修改完后,代码冗余太多。都是为了更好的用户体验,慢慢也能理解。在那之后的几个移动端项目里,表单部分基本不会用到UI组件库。但是弹出层部分没有过多的限制,据我了解到的产品内部最统一的就是弹出层。如果有同学想用owl-ui的弹出层部分的话,可以放心用,支持按需加载。
第三点:快速出货,提升成就感
我喜欢把长期计划拆解成多个很小的事情来做,就是制定很多小目标。好比游戏进度条一样,使其量化。之所以这么做的原因是,我能周期性的看到我的工作成果,这样可以激励自己,提升信心。
在弹出层组件中,mixins做好之后,像toast、dialog、drawer组件只剩下设计api部分而已。而picker组件是基于drawer组件来实现的内容部分而已。当picker组件实现完成,这时已经说明表单的select组件也已经完成了。说起来简单,其实做起来也不难。
最后在使用弹出层组件时,我想用api调用的方式来使用它。这里我借鉴了cube-ui的vue-create-api,但是因为部分方法不太适合我,所以我稍加改动,借鉴(抄)到自己的库中。
比如Toast组件,官网给出的使用方式如下:
const toast = this.$createToast({
time: 1000,
txt: 'Toast time 1s'
})
toast.show()
复制代码
我是个懒人,对我来说使用一个消息提醒要写这么多,我就觉得很烦恼,所以我在owl-ui中把vue-create-api稍加改造后,Toast使用方式如下:
this.$toast('欢迎光临')
复制代码
清爽了很多。
其他类型组件使用情况,有人喜欢整套使用,有人喜欢部分使用。而我属于后者。
结语
我写组件库的目的就两点。第一点可以帮助我重新梳理一遍vue的知识体系,了解到自身的不足,不断的克服困难,让自己成长。第二点结识更多圈内的朋友,提高见识。我会持续更新迭代owl-ui组件库,欢迎喜欢技术的朋友多提建议。最后附上吴军博士说过话,这句话让我终身受益。
什么事情从0分做到50分靠常识,从50分做到90分靠技术,从90分做到100分靠的是艺术。做到90分我们可以通过努力能达到,至于是否能做到更好,就依人而定了。
链接
UI组件库从0到1开发心得
github
owl-ui主页
vue-create-api更改版
less版1px方案
祝工作顺利
邓文斌
2019年5月20日