HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>数字输入框组件——实战</title>
<style>
[v-cloak]{
display: none;
}
.step{
width: 70px!important;
}
</style>
<link rel="stylesheet" href="/node_modules/bootstrap/dist/css/bootstrap.min.css">
</head>
<body>
<div id="app" v-cloak>
<input-number v-model="value" :max="40" :min="0" :step-max='10' @on-change="updateValue"></input-number>
</div>
<script type="text/javascript" src="/node_modules/vue/dist/vue.js"></script>
<script type="text/javascript" src="js/input-number.js"></script>
<script type="text/javascript" src="js/index.js"></script>
</body>
</html>
JS
input-number.js
Vue.component("input-number", {
template: `
<div class="container">
<div class="row">
<form class="form form-inline">
<input class='form-control' type='number' :value='currentValue' @change='handlerChange' @input='handlerChange'>
<input class='form-control step' type='number' :value='currentStep' @input='changeStep'>
<button class='btn btn-primary' type='button' @click='reduce' :disabled='currentValue<=min'>-</button>
<button class='btn btn-primary' type='button' @click='crease' :disabled='currentValue>=max'>+</button>
</form>
</div>
</div>
`,
props: {
max: {
type: Number,
default:Infinity
},
min:{
type:Number,
default:-Infinity
},
stepMax: {
type: Number,
default:Infinity
},
stepMin:{
type:Number,
default:1
},
value:{
type:Number,
default:0
},
step:{
type:Number,
default:1
}
},
data (){
return {
currentValue: this.value,
currentStep: this.step,
}
},
watch:{
currentValue(val){
this.updateValue(val);
this.$emit("input",val);
this.$emit("on-change",val)
},
currentStep(val){
this.$emit("input",val);
}
},
methods:{
crease: function(){
if(this.currentValue>=this.max) return;
var step = this.currentStep;
this.currentValue+=step;
},
reduce:function(){
if(this.currentValue<=this.min) return;
var step = this.currentStep;
this.currentValue-=step;
},
handlerChange:function(event){
var val = event.target.value.trim();
if(val){
val = Number(val);
this.currentValue = val;
this.updateValue(val);
}else{
event.target.value = this.currentValue;
}
},
updateValue:function(val){
console.log(typeof(val));
if(val>this.max) val = this.max;
if(val<this.min) val = this.min;
this.currentValue = val;
},
updateStep:function(val){
if(val>this.stepMax) val = this.stepMax;
if(val<this.stepMin) val = this.stepMin;
this.currentStep = val;
},
changeStep:function(event){
var val = event.target.value.trim();
if(val){
val = Number(val);
this.currentStep = val;
this.updateStep(val);
}else{
event.target.value = this.currentStep;
}
},
},
mounted(){
this.updateValue(this.value);
this.updateStep(this.step);
}
})
index.js
var vm = new Vue({
el: "#app",
data: {
value: 20,
step: 1
},
methods: {
updateValue: function(val) {
this.value = val;
}
}
})
网友评论