Когда значение ввода больше 10, оно всегда будет испускать 10 для родительского компонента, но значение не изменяет (всегда = 10), поэтому не будет запускать реактивность ,
Одно решение , всегда сначала выдается фактическое значение (= parseInt(event.target.value)
), а затем выдается максимальное значение (= Math.min(newValue, this.maxValue)
) в vm.$nextTick()
Другим решением является использование this.$forceUpdate()
.
Обновлено : Как отметил @Husam Ibrahim, атрибут max
будет работать также как <input :value="value" type="number" @input="onInput" @keydown :max="maxValue">
Ниже демо для $nextTick
.
Vue.component('custom-input', {
template: '#custom-input',
props: {
value: Number,
maxValue: Number
},
methods: {
onInput(event) {
const newValue = parseInt(event.target.value)
const clampedValue = Math.min(newValue, this.maxValue)
this.$emit('input', newValue)
this.$nextTick(()=>{
this.$emit('input', clampedValue)
})
}
}
})
new Vue({
el: "#app",
data: {
value: 5
},
methods: {
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<template id="custom-input">
<div>
<input
:value="value"
type="number"
@input="onInput"
>
</div>
</template>
<div id="app">
<div>
<span>Value: {{ value }}</span>
<custom-input v-model="value" :max-value="10"/>
</div>
</div>
Ниже демо для vm.$forceUpdate
.
Vue.component('custom-input', {
template: '#custom-input',
props: {
value: Number,
maxValue: Number
},
methods: {
onInput(event) {
const newValue = parseInt(event.target.value)
const clampedValue = Math.min(newValue, this.maxValue)
this.$emit('input', clampedValue)
this.$forceUpdate()
}
}
})
new Vue({
el: "#app",
data: {
value: 5
},
methods: {
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<template id="custom-input">
<div>
<input
:value="value"
type="number"
@input="onInput"
>
</div>
</template>
<div id="app">
<div>
<span>Value: {{ value }}</span>
<custom-input v-model="value" :max-value="10"/>
</div>
</div>
Ниже демо использовать атрибут max
.
Vue.component('custom-input', {
template: '#custom-input',
props: {
value: Number,
maxValue: Number
},
methods: {
onInput(event) {
const newValue = parseInt(event.target.value)
const clampedValue = Math.min(newValue, this.maxValue)
this.$emit('input', clampedValue)
}
}
})
new Vue({
el: "#app",
data: {
value: 5
},
methods: {
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<template id="custom-input">
<div>
<input
:value="value"
type="number"
@input="onInput"
:max="maxValue"
>
</div>
</template>
<div id="app">
<div>
<span>Value: {{ value }}</span>
<custom-input v-model="value" :max-value="10"/>
</div>
</div>