知识点
-
v-model
双向绑定value
-
父组件向子组件传递数据
props
-
解决单向数据流的问题,在子组件的
data
选项中声明一个currentValue
,默认使用value
的值data: function() { return { currentValue: this.value, prop_step: 10 }; }
-
watch
选项监听prop
或data
的改变watch: { currentValue: function (val) { this.$emit('input',val); this.$emit('on-change',val); }, value:function (val) { this.updateValue = val; } }
-
第一次初始化的时候对
value
进行过滤updateValue:function (val) { if(val > this.max) val = this.max; if(val < this.min) val = this.min; this.currentValue = val; }
-
v-on
事件监听,加减数据,在子组件的methods
中添加方法<button @click="handleDown" :disabled="currentValue <= min">-</button> <button @click="handleUp" :disabled="currentValue >= max">+</button>
-
在表单中增加对键盘上下键的支持
@keyup.up='handleUp' @keyup.down='handleDown'
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数字输入框组件</title>
</head>
<body>
<div id="app">
<input-number v-model = 'value' :max = '10' :min = '0'></input-number>
</div>
<template id="input-number">
<div class="input-number">
<input @keyup.up='handleUp' @keyup.down='handleDown' type="text" :value="currentValue" @change="handleChange" @keyup.up='handleUp' @keyup.down='handleDown'/>
<button @click="handleDown" :disabled="currentValue <= min">-</button>
<button @click="handleUp" :disabled="currentValue >= max">+</button>
</div>
</template>
<script src="../js/vue.js"></script>
<script>
Vue.component('input-number', {
template: '#input-number',
props: {
max: {
type: Number,
default: Infinity
},
min: {
type: Number,
default: -Infinity
},
value: {
type: Number,
default: 0
}
},
data: function() {
return {
currentValue: this.value,
prop_step: 10
};
},
watch: {
currentValue: function (val) {
this.$emit('input',val);
this.$emit('on-change',val);
},
value:function (val) {
this.updateValue = val;
}
},
methods:{
//过滤出正确的currentValue
updateValue:function (val) {
if(val > this.max) val = this.max;
if(val < this.min) val = this.min;
this.currentValue = val;
},
handleDown:function () {
if (this.currentValue <= this.min) return;
this.currentValue -= this.prop_step;
},
handleUp:function () {
if (this.currentValue >= this.max) return;
this.currentValue += this.prop_step;
},
handleChange:function (event) {
var val = event.targrt.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;
}
}
},
//第一次初始化时,也对value进行过滤
mounted:function () {
this.updateValue(this.value);
}
});
let app = new Vue({
el: '#app',
data:{
value: 5
}
});
</script>
</body>
</html>