最近閑來無事,接了個組件庫開發(fā)的活,在這里先記錄一下~
!!! 寫作不易,如要轉(zhuǎn)裁,請標(biāo)明轉(zhuǎn)載出處。
本文借鑒于element-ui組件庫的源碼
1. 項目結(jié)構(gòu)
可以去 github 自行下載 element-ui 源碼,以下是新建組件的步驟簡介,只想看 區(qū)間輸入框 實現(xiàn)的同鞋可以自行跳過~
1.1 新建組件文件
packages下新建 range-input 文件夾,在其下面新建 index.js
import RangeInput from './src/range-input.vue';
RangeInput.install = function (Vue) {
Vue.component(RangeInput.name, RangeInput);
}
export default RangeInput;
1.2 新建組件 vue
packages -> range-input -> src -> range-input.vue
具體的組件邏輯代碼都是在這里寫的?。。?/p>
1.3 引入組件
src -> index.js
1.4 新建md說明文檔
examples -> components ->dosc -> range-input.md
1.5 新建文檔文件
examples -> components ->views\components-> range-input.vue
在文件中引入步驟4的文檔文件,控制說明文檔的樣式也可以寫在這里~
<template>
<div class="wrapper">
<demo></demo>
</div>
</template>
<script>
import demo from 'examples/components/docs/range-input.md'
export default {
components: {
demo
}
}
</script>
1.6 在菜單中加新組建的路由
examples -> router ->menu.js
2. 區(qū)間輸入框組件
2.1 區(qū)間輸入框效果圖

區(qū)間輸入框效果圖
2.2 調(diào)用實例
由下面的使用組件實例來看,雙向綁定了變量 moneyData 為數(shù)組格式,數(shù)組中第一個元素為區(qū)間輸入的起始值,數(shù)組中的第二個元素為區(qū)間輸入的結(jié)束值。
<range-input
type="money"
placeholder="請輸入金額"
clearable
v-model="moneyData"
@input="moneyInput"
@focus="moneyFocus"
@blur="moneyBlur"
@change="moneyChange">
</range-input>
2.3 組件編碼
<template>
<div class="range-input"
:class="{'disabled': disabled}"
:style="styleName"
@mouseover="handleMouseover"
@mouseout="handleMouseout">
<div class="range-input-box"
:class="{'active': rangeInputFocus, 'error': svgType == 'error'}">
<div class="input-box">
<input type="text"
class="range-input"
:disabled="disabled"
:placeholder="placeholder"
v-model="rangeInputs[0]"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange">
</div>
<div class="range-input-divider"></div>
<div class="input-box">
<input type="text"
class="range-input"
:disabled="disabled"
:placeholder="placeholder"
v-model="rangeInputs[1]"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
@change="handleChange">
</div>
<svg class="svgClass"
@click="svgType == 'del' && handleClear()"></svg>
</div>
</div>
</template>
2.4 方法編碼
props中的是暴露出去的參數(shù)
<script>
export default {
name: 'RangeInput',
props: {
type: { // 類型 便于表單驗證 區(qū)間是只能輸入錢數(shù) 還是整數(shù)等
type: String,
default:'input'
},
width: { // 組件的寬度
type: String,
default: '256px'
},
placeholder: { // 輸入框占位文本
type: String,
default: ''
},
value: { // 綁定值
type: Array,
default: []
},
clearable: { // 是否支持清空
type: Boolean,
default: false
},
disabled: { // 是否禁用
type: Boolean,
default: false
}
},
data () {
return {
svgClass: '',
rangeInputFocus: false,
rangeInputs: [...this.value],
svgType: this.type,
validateState: true, // 表單驗證結(jié)果
errorMessage: '',
}
},
computed: {
styleName () {
return {
width: this.width
}
},
svgName () {
return this.svgType == 'money' ? '#svg_sales' :
this.svgType == 'del' ? '#svg_close' : '#svg_draw'
}
},
methods: {
handleInput () {
this.$emit('input', [...this.rangeInputs]);
},
handleFocus (event) {
this.rangeInputFocus = true;
this.$emit('focus', event);
},
handleBlur (event) {
this.rangeInputFocus = false;
this.$emit('blur', event);
},
handleChange () {
this.$emit('change', [...this.rangeInputs]);
},
hanleMouseover () {
if (!this.validateState) {
this.svgType = 'error';
} else {
this.rangeInputs && this.rangeInputs.length && this.clearable ? this.svgType = 'del' : this.svgType = this.type;
}
},
handleMouseout () {
if (!this.validateState) {
this.svgType = 'error';
} else {
this.svgType = this.type;
}
},
handleClear () {
this.rangeInputs = ['', ''];
this.$emit('input', null);
}
}
};
</script>
2.5 樣式編碼
<style lang="scss" scoped>
%highlight {
position: absolute;
bottom: 0;
left: 0;
content: '';
width: 100%;
height: 1px;
}
.range-input{
padding: 4px 0;
.range-input-box{
position: relative;
display: flex;
align-items: center;
height: 32px;
line-height: 32px;
border-radius: 8px;
background: $c129;
overflow: hidden;
&.active:after{
@extend %hightlight;
background: $a001;
}
&.error:after{
@extend %hightlight;
background: $c001;
}
.input-box{
width: calc((100% - 6px - 18px -6px) / 2);
.range-input{
width: 100%;
padding: 0 6px 0 8px;
@include body1;
height: 32px;
line-height: 32px;
box-sizing: border-box;
background: transparent;
color: $c121;
&::-webkit-input-placeholder{
color: $c125;
}
&::-moz-placeholder{
color: $c125;
}
}
}
.range-input-divider{
content: '';
width: 6px;
height: 1px;
background: $c126;
}
}
&:hover{
.range-input-box{
background: $c128;
}
}
&.disabled{
.range-input-box{
cursor: not-allowed;
background: $c130;
}
}
}
</style>
第一次參與組件庫的研發(fā)與制作,在實現(xiàn)上肯定存在不足的地方,歡迎大家來評論區(qū)里留言,感謝大家的批評與指正~
如果本文對你有所幫助,感謝點一顆小心心,您的支持是我繼續(xù)創(chuàng)作的動力!