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

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


最终效果图

需求:

  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
    }
});
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • HTML 5 HTML5概述 因特网上的信息是以网页的形式展示给用户的,因此网页是网络信息传递的载体。网页文件是用...
    阿啊阿吖丁阅读 5,121评论 0 0
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 137,103评论 19 139
  • 王者风范诗文雅, 兴致文赋写天下。 舟曲滑台底蕴厚, 好运文坛盛世华!
    行者顺达阅读 316评论 0 0
  • 1、注释:cmd + option + / 2、Option + click 查看 变量类型 3、输入color ...
    乱尘阅读 283评论 0 0
  • 前言 有幸在5月29日至6月3日有机会到日本旅游,公司福利简直赞啊。几个同事一起去,出发前觉得还是自由行比较随意,...
    夕枫晚照阅读 336评论 1 0

友情链接更多精彩内容