《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作对应的修改即可