美文网首页
Vue组件库开发—input区间输入组件

Vue组件库开发—input区间输入组件

作者: 一名有马甲线的程序媛 | 来源:发表于2021-05-29 15:36 被阅读0次

最近闲来无事,接了个组件库开发的活,在这里先记录一下~
!!! 写作不易,如要转裁,请标明转载出处。
本文借鉴于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>

第一次参与组件库的研发与制作,在实现上肯定存在不足的地方,欢迎大家来评论区里留言,感谢大家的批评与指正~
如果本文对你有所帮助,感谢点一颗小心心,您的支持是我继续创作的动力!

相关文章

  • Vue组件库开发—input区间输入组件

    最近闲来无事,接了个组件库开发的活,在这里先记录一下~!!! 写作不易,如要转裁,请标明转载出处。本文借鉴于ele...

  • vue element组件库限制只能输入数字

    vue element组件库限制只能输入数字,且保留小数后两位 项目需求el-input组件输...

  • 如何开发vue、react、angular的组件库教程

    关键词:vue,react,angular,开发,封装,ui组件,组件库,常用组件 目标:开发相应的组件库vue-...

  • 五、Vue生态介绍

    一、Vue组件库Vue组件库是使用Vue框架开发的组件,一般包含着开发者可以直接使用的基础组件:表单、弹窗、表格等...

  • vue.js - 组件库汇总

    1. 组件库和开发框架汇总 vue组件库和开发框架汇总https://yq.aliyun.com/articles...

  • vue(2)

    Vue组件化开发 组件化开发的思想 组件的注册 组件间的数据交互 组件插槽的用法 Vue调试工具的用法 组件开发思...

  • Angular框架中的@Input()属性装饰器

    1、前言 angular中,Input是属性装饰器,用来定义组件内的输入属性。在实际的开发中主要用于父组件向子组件...

  • 小程序使用 vant 快速创建页面

    vant UI 组件库是有赞前端团队开发的一个 Vue 组件库,提供了一整套的 UI 基础组件和业务组件,通过 v...

  • 深度作用选择器

    在 Vue 的开发中,我们经常会用到外部组件库,例如 element,当使用 element 组件库中的某一个组件...

  • vue 局部组件递归

    vue只有全局注册的组件才能递归调用吗? 最近在开发 npm 组件库,需要递归使用组件,组件间存在相互依赖关系。搜...

网友评论

      本文标题:Vue组件库开发—input区间输入组件

      本文链接:https://www.haomeiwen.com/subject/mgnysltx.html