<!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.在组件的props里添加step,同时在data中return出this.step,Vue父实例中填写step,此时stepNum的值仍为default,此时想要获取父实例的值应通过父链。(注释掉的那行)
随后在methods作对应的修改即可