《Vue.js实战》章七 组件——数字输入框组件

 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>数字输入框组件</title>
</head>
<body>
    <div id="app1">
        <input-number v-model="value" :max="10" :min="0"></input-number>
    </div>
    <!-- <div id="app2">
        <input type="text" @change="print" v-model="test">
        <p>{{ test }}</p>
    </div> -->
    <script src="Vue.2.6.10.js"></script>
</body>
<script>
    function isValueNumber(value){
        return (/(^-?[0-9]+.{1}d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}&)/).test(value + '');
        // test()方法,用于检测一个字符串是否符合某个模式
    }

    Vue.component('input-number',{
        template:'
        <div class="input-number">
        <input 
            type="text"
            @focus="keyControl"
            :value="currentValue"
            :step=this.$parent.step
            @change="handleChange">
        <button 
            @click="handleDown" 
            :disabled = "currentValue <= min">-</button>
        <button 
            @click="handleUp" 
            :disabled = "currentValue >= max">+</button>
        </div>',
        props:{
            max:{
                type:Number,
                default:Infinity
            },
            min:{
                type:Number,
                default:-Infinity
            },
            value:{
                type:Number,
                default:0
            },
            step:{
                type:Number,
                default:1
            }
        },
        data() {
            return {
                currentValue:this.value,
                stepNum:this.step
                // stepNum:this.$parent.step
            }
        },
        watch:{
            currentValue:function(val){
                this.$emit('input',val);
                this.$emit('on-change',val);
            },
            value:function(val){
                this.updateValue(val);
            }
        },
        methods: {
            keyControl:function(){
                var _this = this;
                document.onkeydown = function(e){
                if(document.getElementsByTagName('input')){
                    if(e.keyCode == 38){
                        _this.handleUp();
                    }else if(e.keyCode == 40){
                        _this.handleDown();
                    }
                }
            }
            },
            handleDown:function(){
                if(this.currentValue <= this.min) return;
                console.log(this.stepNum);
                this.currentValue -= this.stepNum;
                // 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;
                }
            }
        },
        mounted() {
            this.updateValue(this.value);
            //练习部分
            var _this = this;
            // document.onkeydown = function(e){
            //     if(document.getElementsByTagName('input')){
            //         if(e.keyCode == 38){
            //             _this.handleUp();
            //         }else if(e.keyCode == 40){
            //             _this.handleDown();
            //         }
            //     }
            // }
        },
    });
    var app1 = new Vue({
        el:"#app1",
        data:{
            value:5,
            step:5,
        },
    });

    // var app2 = new Vue({
    //     el:"#app2",
    //     data:{
    //         test:''
    //     },
    //     methods:{
    //         print:function(event){
    //             console.log(this,event,event.target.value,this.test);
    //         }
    //     }
    // });
</script>
</html>

这一个组件的思路和代码比较好理解,因此没有太多的注释。这一章的另一个组件(标签页组件)要更具有挑战性一些,思路会写的仔细一些。

《Vue.js》实战 组件 练习:

1.输入框聚焦时增加对键盘上下按键的支持:

两种方法:

1.1:

在输入框上绑定聚焦事件,

在methods中执行,注意不能用onkeypress,方向键触发不了。

 

1.2:在子组件的mounted钩子里绑定(这里应该要用document.activeElement判定聚焦的)

 

 

2.增加一个控制步伐的prop-step,当设置为10时点击加号按钮+10..

还是两种方法,但区别只在于数据的传递

1.在组件的props里添加step,同时在data中return出this.step,Vue父实例中不填写step,此时stepNum的值即为default。

2.同上,但不填写default,会出现NaN,因为此时父组件中没有v-bind:step="1",直接this.step是一个空变量。

3.在组件的props里添加step,同时在data中return出this.step,Vue父实例中填写step,此时stepNum的值仍为default,此时想要获取父实例的值应通过父链。(注释掉的那行)

 

随后在methods作对应的修改即可

原文地址:https://www.cnblogs.com/linbudu/p/11003235.html