美文网首页
Vue2.0 完成数字输入框组件

Vue2.0 完成数字输入框组件

作者: yancolin | 来源:发表于2018-04-17 15:52 被阅读272次

    下面是最终效果图,简陋版的。


    最终效果图

    需求:

    1. 输入框只能输入数字,初始值为5。点击加减,相应减1; 点击+10,输入框数字相应加10。此输入框最大值为100,最小值为0;
    2. 输入框聚焦的时候,键盘上下相应加减1。

    分为index.html,input-number.js,index.js 三个文件。
    index.html 入口页
    input-number.js 数字输入框组件
    index.js 根实例
    代码如下:

    index.html

    注:

    1. 给input-number绑定一个v-model实现双向数据,赋初始的最大值为100,最小值为0,步长的值对应一次性加10的按钮。
    2. :是语法糖,代表v-bind。
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="app">
        <input-number v-model="value" :max="100" :min="0" :step="10"></input-number>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
    <script src="input-number.js"></script>
    <script src="index.js"></script>
    </body>
    </html>
    
    input-number.js

    注:
    1.props可以对父组件的变量进行校验。
    2.组件中要使用data,必须是函数且有返回值。
    3.给组件input赋初始值currentValue,通过组件中的data给currentValue赋值。
    4.单击事件:v-on:click="方法" @click="方法"(简写)
    双击事件:v-on:dblclick="方法" @dblclick="方法"(简写)

        return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value);
    }
    
    Vue.component('input-number',{
        template: ' <div class="input-number">'
        // + '<input type="text" :value="currentValue" @change="handleChange" @focus="handleInput">'
        + '<input type="text" :value="currentValue" @change="handleChange" @keydown="handleKeydown">'
        + '<button @click="handleDown" :disabled="currentValue <= min">-</button>'
        + '<button @click="handleUp" :disabled="currentValue >= max">+</button>'
        + '<button @click="handleAdd" :disabled="currentValue + 10 >= max">+10</button>'
        + '</div>',
        props: {
            max: {
                type: Number,
                default: Infinity
            },
            min: {
                type: Number,
                default: -Infinity
            },
            value:{
                type: Number,
                default: 0
            },
            step:{
                type:Number,
                default:10
            }
        },
        data:function () {
            return {
                currentValue: this.value
            }
        },
        watch:{
            currentValue: function (val) {
                this.$emit('input',val);
                this.$emit('on-change',val);
            },
            value: function (val) {
                this.updateValue(val);
            }
        },
        methods:{
            handleDown: function () {
                if( this.currentValue <= this.min ) return;
                this.currentValue -= 1;
            },
            handleUp: function () {
                if( this.currentValue >= this.max ) return;
                this.currentValue += 1;
            },
            updateValue: function (val) {
                if( val > this.max ) val = this.max;
                if( val < this.min ) val = this.min;
                this.currentValue = val;
            },
            handleChange: function (event) {
                var val = event.target.value.trim();
                var max = this.max;
                var min = this.min;
    
                if(isValueNumber(val)){
                    val = Number(val);
                    this.currentValue = val;
    
                    if(val > max){
                        this.currentValue = max;
                    }else if( val < min ){
                        this.currentValue = min;
                    }
                }else{
                    event.target.value = this.currentValue;
                }
            },
            handleKeydown: function (event) {
                // 上
                if(event.keyCode == 38){
                    this.currentValue += 1;
                    if( this.currentValue > this.max ){
                        this.currentValue = this.max;
                    }
                }
                // 下
                if(event.keyCode == 40){
                    if(this.currentValue <= 0) return;
                    this.currentValue -= 1;
                }
            },
            handleAdd: function () {
                this.currentValue += this.step;
                if( this.currentValue >= this.max ){
                    this.currentValue = this.max;
                }
            }
            // handleInput: function () {
            //     // 这是Input框获取焦点事件
            // }
        },
        mounted: function () {
            this.updateValue(this.value);
        }
    });
    
    index.js
    var app = new Vue({
        el: '#app',
        data:{
            value:5
        }
    });
    

    相关文章

      网友评论

          本文标题:Vue2.0 完成数字输入框组件

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