preface
The world of Vue is already full of various UI libraries, notably ElementUI, Iview, MuseUI, etc., which are often used in our daily business development. Engineers who only use the UI library are ridiculed as API callers, a kind of contempt among engineers that will have to be returned.
Recently, I was at home, trying to feel the development process from the perspective of a mature UI library. After seeing these excellent codes, I really felt that my code smelled like shit! Without further ado, let’s start building our own UI library, starting with a look at how buttons are developed.
Use of buttons
Before we start developing buttons, let’s take a look at how they are used and what major properties or functions they have. This will be useful and significant for the rest of the API definition.
The main properties of a button are as follows:
- Whether the rounded
- Is there a border
- Is it clickable (disabled)
- color
- The size of the
- .
There are many more properties, but we won’t go over them here, some properties are developed, others are just copied; Let’s see how this works in real life:
< xCH-button color="primary" :disabled="true" :noBorder="true" circle size="m"> </ xCH-button >Copy the code
Directory planning before development
Clear directory planning, for the following code to bring unexpected readability. As time goes on, a project with staff changes tends to become larger and more difficult to maintain. It’s best to plan everything out in the early stages, but how many people can do that? Take a look at the directory for our button component:
Vue-cli 4.0 scaffolding is used in this project, which is roughly the same as the directory generated in previous versions. The code we wrote is basically in the SRC directory, where components is our.vue file, style is our style file, we used less in this project, which is similar to other CSS preprocessors. The more specific code logic is explained in detail below.
The definition of props
The minimum requirement for this article is that you have a basic knowledge of VUE. Before developing a component, it is best to map out its capabilities and associated properties and apis. In particular, don’t mess with the API. Any incompatible changes are a sign of immaturity and are irresponsible to the user of the component. This is why we always choose a mature and good framework, nobody wants to change incompatible code every once in a while. To get back to the topic, let’s first define the props we need:
props: {
circle: Boolean./ / the rounded
noBorder: Boolean./ / frame
disabled: Boolean./ / click
color: String./ / color
textColor: String.// Text color
size: {
type: String,
validator(value) {
return ["l"."m"."s"."xs"].indexOf(value) ! =- 1; }}// Button size
}
Copy the code
Class: btn-circle, size: l, btn-l, class: btn-l, class: btn-l All the other properties are pretty much the same.
The computed properties of the style
Props are passed in to control whether or not a style is applied. We use vue’s object syntax
to define a calculated attribute buttonCls controls the style class section.
computed: {
buttonCls() {
return{[`${prefix}`] :true[`${prefix}-circle`] :!!!!!this.circle,
[`${prefix}-no-border`] :this.noBorder === true[`${prefix}-The ${this.color}`] :!!!!!this.color,
[`${prefix}-text-The ${this.textColor}`] :!!!!!this.textColor,
[`${prefix}-The ${this.size}`] :!!!!!this.size }; }}Copy the code
The neat code is nice, with the variable prefix being a self-defined prefix, which is nice to distinguish between other UI libraries, ElementUI starting with el- and Iview starting with I -. Such an operation, immediately lofty up. It’s a royal button, haha.
template
The template section is relatively simple, and basically applies the props and calculation properties to the Button tag:
<template> <button type="button" :class="buttonCls" :disabled="!! this.disabled" @click="click" > <slot></slot> </button> </template>Copy the code
Main event: style
Here, the logic part is basically finished, a total of less than 50 lines of code, although el-Button is not as functional as ElementUI, but it is still a small number of everything, interested students can copy el-Button to further expand. Let’s focus on how to plan and write clean less code (this part of the code really amazes me, I have not paid much attention to CSS code before).
Before we start writing code, let’s review the key points:
- The global styles are pulled out into separate variable files, as here
var.less
When writing a large project or plug-in library and facing mountains of code,People who can reuse code are happy
What is left is to be miserable with mud people every day. - Each component has its own LESS file, here
button.less
less
Syntax is very powerful, usually the most used is nested syntax and variable patterns, in factless
There are a lot of powerful functions, such as functions, mixing, etc., are worth us to understand and learn
Let’s take a look at the var. Less file. There are a lot of variables in the var. Less file, such as color and padding.
@prefix: xch-;
/ / color
@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;
/ / button 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;
Copy the code
Button.less code, I use the method of annotation, as detailed as possible to explain the mystery
@btn-prefix: ~"@{prefix}btn"; // Define prefixes, which are common in UI component libraries
// Define a function to easily control color switching
// Darken and lighten are less ways to lighten
.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; .// The essence of color switching
&.@{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; }}// Unclickable style
&[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; }}// Control button size, actually control the padding
&.@{btn-prefix}-l {
padding: @button-size-l-padding;
}
&.@{btn-prefix}-m {
padding: @button-size-m-padding; }... }Copy the code
Global registration and use
The last step is to register this component globally. This part of the code is in the entry file main.js, relatively simple and not too tired to describe; For those of you who are interested, consider how to define another component, button-group, to accomplish the combination of buttons.
The source code
There are also some details of the code and the specific button effects, which are not mentioned here, you can go to the source code to see more detailed code. Or directly downloaded to the local, run, run: git clone https://github.com/xch1029/vue-study.git. On the other hand, implementing some UI library-level code on your own can really improve things.