最近闲来无事,接了个组件库开发的活,在这里先记录一下~
!!! 写作不易,如要转裁,请标明转载出处。
本文借鉴于element-ui组件库的源码
1. 项目结构
可以去 github 自行下载 element-ui 源码,以下是新建组件的步骤简介,只想看 区间输入框 实现的同鞋可以自行跳过~
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
具体的组件逻辑代码都是在这里写的!!!
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. 区间输入框组件
2.1 区间输入框效果图
区间输入框效果图2.2 调用实例
由下面的使用组件实例来看,双向绑定了变量 moneyData 为数组格式,数组中第一个元素为区间输入的起始值,数组中的第二个元素为区间输入的结束值。
<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中的是暴露出去的参数
<script>
export default {
name: 'RangeInput',
props: {
type: { // 类型 便于表单验证 区间是只能输入钱数 还是整数等
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, // 表单验证结果
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>
第一次参与组件库的研发与制作,在实现上肯定存在不足的地方,欢迎大家来评论区里留言,感谢大家的批评与指正~
如果本文对你有所帮助,感谢点一颗小心心,您的支持是我继续创作的动力!
网友评论