vue --- > vue.js实战基础篇课后练习

练习1:在输入框聚焦时,增加对键盘上下键按键的支持,相当于加1和减1
练习2:增加一个控制步伐的prop-step,比如设置为10,点击加号按钮,一次增加10

思路:

// 考虑到子模板的复用性,即在父模板中复用如下:
<input-number v-model="value" :max="10" :min="0" :step="3"></input-number>
// v-model将input中的值和父模板data下面value的值绑定到一起
// 可以通过:max,:min限制输入框的最大最小值
// 通过:step来设置子模版点击加号时的步伐(即,一次加多少)

几个补充:
@focus: 用于绑定input的聚焦事件
@blur: 用于绑定input的失去焦点事件
@keyup.down: 绑定键盘的向下键
@keyup.up: 绑定键盘的向上键

总体代码如下:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
    <div id="app">
        <input-number v-model="value" :max="10" :min="0" :step="3"></input-number>
    </div>

<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script>
<script>
    Vue.component('input-number',{
        template:'\
        <div class="input-number">\
            <input type="text" :value="currentValue" @change="handleChange" @focus="handleFocus" @blur="handleBlur" @keyup.down="handleArrowDown" @keyup.up="handleArrowUp">\
            <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:function (){
            return {
                currentValue: this.value,
                isFocus:false
            }
        },
        methods:{
            handleUp:function() {
                this.currentValue += this.step;
            },
            handleDown:function() {
                this.currentValue -= this.step;
            },
            isValueNumber:function(value) {
                return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value + '');
            },
            handleChange:function(event){
                let val = event.target.value.trim();
                let max = this.max;
                let min = this.min;
                
                if(this.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;
                }
            },
            updateValue:function(val){
                if(val > this.max) val = this.max;
                if(val < this.min) val = this.min;
                this.currentValue = val;
            },
            handleFocus:function(){
                this.isFocus = true
            },
            handleBlur:function(){
                this.isFocus = false
            },
            handleArrowDown:function(){
                if(this.isFocus){
                    this.handleDown();
                }
            },
            handleArrowUp:function(){
                if(this.isFocus){
                    this.handleUp();
                }
            }
        },
        watch:{
            currentValue: function(val) {
                this.$emit('input',val);
            },
            value: function(val){
                this.updateValue(val);
            }
        }
    })
    const app = new Vue({
        el:'#app',
        data:{
            value:5
        }
    })
</script>

</body>
</html>

参考《Vue.js实战》P98~P106

猜你喜欢

转载自blog.csdn.net/piano9425/article/details/94491098