在Vue
的世界中已经充满了各类各样的UI库了,尤为出名的有ElementUI、Iview、MuseUI等,这几个也是咱们平常业务开发中常用的UI库。只使用UI库的工程师被调侃为api调用师
,这算是一种工程师之间的鄙视了,这种鄙视早晚要还回去的。javascript
最近在家比较闲,尝试着以成熟UI库的视角来感觉下其的开发过程,看了这些优秀的代码,真的以为本身的代码有点屎味
了!很少说了,让咱们开始打造本身的UI库吧,首先看下按钮是怎么开发出来的。css
在正式开发按钮以前,咱们先看下按钮是如何使用的,以及有哪些主要属性或者功能。这对接下来的api定义是颇有用处的,意义重大。vue
按钮的主要属性有这么几点:java
其实还有更多的属性,这里咱们不赘述了,知道了某些属性的开发过程,其余的也只是照葫芦画瓢的;再来看下真实场景中是如何使用的:git
<xch-button color="primary" :disabled="true" :noBorder="true" circle size="m">按钮</xch-button>
复制代码
清晰的目录规划,能为后面的代码带来意想不到的可读性。一个项目随着时间的推移,人员的变更,每每会变得愈来愈大,愈来愈难维护。能在前期就规划好一切固然是最好的,可是又有几人能作到呢。看下咱们这个按钮组件的目录:github
本项目使用的是vue-cli 4.0
脚手架生成的,和之前版本生成的目录大体相同。咱们编写的代码基本都在src
目录下,其中components
里放的是咱们的.vue
文件,style
中放的是样式文件,本项目咱们采用的是less,和其余几个css预处理器都差很少。更具体的代码逻辑,在下文会依次详细解说。vue-cli
本文的最低要求是你已经具有了vue的基础知识
。在开发一个组件以前,咱们最好的作法是规划好这个组件的能力和相关的属性以及api。特别是api,轻易不要乱改,任何不兼容的修改都是不成熟的标志,对组件的使用者来讲也是不负责任的表现,这也是为何咱们老是选择成熟优秀框架的缘由,没有人但愿隔三差五去修改不兼容的代码。回归正题,咱们首先定义下咱们须要的props:api
props: {
circle: Boolean, // 圆角
noBorder: Boolean, // 边框
disabled: Boolean, // 可点击
color: String, // 颜色
textColor: String, // 文本颜色
size: {
type: String,
validator(value) {
return ["l", "m", "s", "xs"].indexOf(value) != -1;
}
} // 按钮大小
}
复制代码
先说一下思想:这些传入的props,多数是为了控制某个样式的class是否须要应用,好比,circle
传入的话,就表明着应用class: btn-circle
,size
传入'l'的话,就表明着应用class: btn-l
。其余的属性也都大体同样。框架
上文也讲了,props的传入,其实多数是为了控制某个样式是否应用。咱们使用vue的对象语法<div v-bind:class="{ active: isActive }"></div>
来定义一个计算属性buttonCls
控制着样式class这一块。less
computed: {
buttonCls() {
return {
[`${prefix}`]: true,
[`${prefix}-circle`]: !!this.circle,
[`${prefix}-no-border`]: this.noBorder === true,
[`${prefix}-${this.color}`]: !!this.color,
[`${prefix}-text-${this.textColor}`]: !!this.textColor,
[`${prefix}-${this.size}`]: !!this.size
};
}
}
复制代码
整齐划一的代码真好看,其中变量是prefix
是本身定义的前缀,这样能很好的区分其余UI库,ElementUI是以el-
开头,Iview是以i-
开头。这么一操做,马上高大上起来了。不愧是皇家按钮
, 哈哈。
template
部分相对简单些,主要是将props和计算属性应用到button
标签上:
<template>
<button
type="button"
:class="buttonCls"
:disabled="!!this.disabled"
@click="click"
>
<slot></slot>
</button>
</template>
复制代码
写到这里,逻辑部分基本写完了,一共50行不到的代码,虽然没有ElementUI的el-button
的功能齐全,但也算是麻雀虽小五脏俱全吧,有兴趣的同窗能够仿照el-button
进一步扩展。下面咱们重点学习下怎么规划和书写整洁的less代码(这部分代码真的惊艳到我了,我以前一直不重视css的代码)
在动手写代码以前,咱们先梳理下有哪些要点:
var.less
,这个习惯必定要养成,在编写大型的项目或者插件库的时候,面对堆积成山的代码量,会复用代码的人是快乐的
,剩下的就是和稀泥的人,天天痛苦不堪。button.less
less
语法是很强大的,平时用的最多的就是嵌套语法和变量模式,其实less
还有不少的强大的功能,好比函数,混合等,都是很值得咱们去好好理解和学习的咱们先看下var.less文件,里面咱们定义了不少变量,好比,颜色、padding等,不只是button
组件会用到,之后的其余组件也会用到,先大概看下:
@prefix: xch-;
// 颜色
@primary-color : #45b984;
@blue-color : #3B91FF; //info
@green-color : #13CE66; //success
@yellow-color : #FFAE00; //warn
@red-color : #E11617; //error
@white-color : #fff;
//Dark, Gray 1-4 more
@dark-color: #333333;
@dark1-color: #555555;
@dark2-color: #666666;
@dark3-color: #777777;
@dark4-color: #999999;
@gray-color: #c1c1c1;
@gray1-color: #d3d3d3;
@gray2-color: #eeeeee;
@gray3-color: #f3f3f3;
@gray4-color: #f5f5f5;
// 按钮padding
@button-size-normal-padding: 8px 15px;
@button-size-l-padding: 10px 20px;
@button-size-m-padding: 7px 16px;
@button-size-s-padding: 5px 10px;
@button-size-xs-padding: 2px 6px;
// radius
@border-radius : 4px;
//font-size
@font-size : 14px;
// Animation
@animation-time : .3s;
@transition-time : .2s;
@box-shadow-button: 0 1px 1px 0 @gray2-color;
//disabled
@disabled-cursor: not-allowed;
@disabled-color: @dark4-color;
@disabled-border-color: @gray1-color;
@disabled-background-color: @gray4-color;
复制代码
button.less
的代码,我使用了注释的方法,尽可能详细的解说其中的奥妙
@btn-prefix: ~"@{prefix}btn"; // 定义前缀,这是UI组件库通用的作法
// 定义一个函数,方便控制颜色的切换
// 其中的darken和lighten方法是less自带的,变浅或者变深,甚是好用
.btn-color(@color, @percent: 10%) {
background-color: @color;
border-color: darken(@color, @percent);
color: @white-color;
&:hover{
border-color: lighten(@color, @percent);
background-color: lighten(@color, @percent);
}
&:active {
border-color: darken(@color, @percent);
background-color: darken(@color, @percent);
}
}
.@{btn-prefix} {
border: none;
outline: none;
padding: @button-size-normal-padding;
display: inline-block;
border-radius: @border-radius;
font-size: @font-size;
...
// 颜色切换的精髓
&.@{btn-prefix} {
&-primary{
.btn-color(@primary-color)
}
&-red {
.btn-color(@red-color);
}
...
&-no-border{
box-shadow: none;
border-color: transparent !important;
}
&-circle {
border-radius: 20px;
}
}
// 不可点击时的样式
&[disabled] {
cursor: @disabled-cursor;
background-color: @disabled-background-color;
border-color: @disabled-border-color;
color: @disabled-color;
&:hover {
background-color: @disabled-background-color;
border-color: @disabled-border-color;
color: @disabled-color;
}
}
// 控制按钮大小,实际上是控制padding
&.@{btn-prefix}-l {
padding: @button-size-l-padding;
}
&.@{btn-prefix}-m {
padding: @button-size-m-padding;
}
...
}
复制代码
最后就是将本组件注册到全局,这部分代码在入口文件main.js中,比较简单就不累述了;感兴趣的同窗能够思考下怎么定义另外一个组件button-group
来完成按钮的组合使用。
还有些细枝末叶的代码和具体的按钮效果,这里也没有提到,能够去源码查看更多详细的代码。或者直接下载到本地,跑起来,运行下: git clone https://github.com/xch1029/vue-study.git
。附上一句内心话,本身去实现一些UI库级别的代码真的能提高不少
。