<div id="app">
<input-number v-model="value" :max="100" :min="0"></input-number>
</div>
function isValueNumber(value) {
return (/(^-?[0-9]+\.{1}\d+$)|(^-?[1-9][0-9]*$)|(^-?0{1}$)/).test(value+ '');
}
Vue.component('input-number',{
props: {
max: {
type: Number,
default: Infinity
},
min: {
type: Number,
default: -Infinity
},
value: {
type: Number,
default: 0
}
},
template: `
<div class="input-number">
<input type="text" :value="currentValue" @change="handleChange" @keydown="handleChange2" />
<button @click="handleDown" :disabled="currentValue <= min">-</button>
<button @click="handleUp" :disabled="currentValue >= max">+</button>
</div>
`,
data() {
return{
// 保存初次父组件传递的数据
currentValue : this.value,
prop_step: 10
}
},
watch: {
// 监听属性currentValue与value
currentValue(val) {
// currentValue变化时,通知父组件的value也变化
this.$emit('input', val);
},
value(val) {
// 父组件value改变时,子组件currentValue也改变
this.updataValue(val);
}
},
methods: {
updataValue(val) {
if(val > this.max) val = this.max;
if(val < this.min) val = this.min;
this.currentValue = val;
},
// 点击减号 减10
handleDown() {
if(this.currentValue < this.min) return
this.currentValue -= this.prop_step;
},
// 点击加号 加10
handleUp() {
if(this.currentValue > this.max) return
this.currentValue += this.prop_step;
},
// 输入框输入值
handleChange(event) {
var val = event.target.value.trim();
var max = this.max;
var min = this.min;
if(isValueNumber(val)) {
val = Number(val);
if(val > max) {
this.currentValue = max;
}
if(val < min) {
this.currentValue = min;
}
this.currentValue = val;
console.log(this.value);
}else {
event.target.value = this.currentValue;
}
},
// 当聚焦时,按上下键改变
handleChange2(event) {
console.log(event.keyCode)
if(event.keyCode == '38') {
this.currentValue ++;
}
if(event.keyCode == '40') {
this.currentValue --;
}
}
},
// 第一次初始化时,也对value进行过滤
mounted: function() {
this.updataValue(this.value);
}
})
var app = new Vue({
el:'#app',
data:{
value: 5
}
})