Reputation: 77
hopefully you can help me. I want that if input remains empty, it is assigned a value of 0. At the moment of loading my modal the value is 0, if my input is focused, 0 is deleted. If I go to the next input I do not want any input to remain empty
onFocus() {
this.efectivo = '';
},
onFocus1() {
this.tarjeta = '';
},
<td style="background-color: #CEECF5">
<input name="txtd" @focus="onFocus1" v-bind:min="0" v-model="tarjeta" type="number">
</td>
<td style="background-color: #CEECF5">
<input name="txte" @focus="onFocus2" v-bind:min="0" v-model="vales" type="number">
</td>
Upvotes: 0
Views: 1861
Reputation: 90188
As outlined in the documentation whenever you're tempted to use a watch, consider using a computed
instead:
Vue.config.devtools = false;
Vue.config.productionTip = false;
new Vue({
el: '#app',
data: () => ({
t: 0
}),
computed: {
test: {
get() {
return Number(this.t)
},
set(val) {
this.t = Number(val) || 0
}
}
},
methods: {
onBlur() {
this.$refs.test.value = this.test
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<input v-model="test"
type="number"
min="0"
max="100"
placeholder="0"
ref="test"
@blur="onBlur" />
<pre v-html="{test}" />
</div>
The above follows the Store pattern (one source of truth), where data
acts as a local store for your computed property.
If you use Vuex, you should (obviously) read test
value from the store and commit the mutation in the setter.
If you're not using Vuex but still want to export your data
prop so that external components can react to its change, you can use the shiny new Vue.observable()
, added in v2.6
:
Vue.config.devtools = false;
Vue.config.productionTip = false;
const store = Vue.observable({ test: 0 });
new Vue({
el: '#app',
computed: {
test: {
get() {
return Number(store.test)
},
set(val) {
store.test = Number(val) || 0
}
}
},
methods: {
onBlur() {
this.$refs.test.value = this.test
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.11/vue.js"></script>
<div id="app">
<input v-model="test"
type="number"
min="0"
max="100"
placeholder="0"
ref="test"
@blur="onBlur" />
<pre v-html="{test}" />
</div>
Now your store
const can live in a different file, can be imported/exported and you can listen to its changes in any other component by using it inside a computed
property.
Upvotes: 1
Reputation: 10729
From your description, it seems you'd like to implement one input can't be empty when lose focus, and if the value of the input is empty, you'd like to assign zero to it.
I think uses watch will be one option like below demo:
Updated: the value of the input will be one string,
So for first solution: if you'd like to trim the leading zero, uses the modifier=number of v-model
like v-model.number='test1'
.
For second solution: convert it to this.test2 = Number(this.test2)
manually.
new Vue ({
el:'#app',
data () {
return {
test1:0, //uses v-model, actually :value and @input, @input will occurs when text content of input is changed
test2: 0, //uses :value and @change, @change will occurs when lose focus or press 'enter/return',
}
},
watch: {
test1: function (newVal, oldVal) {
if (newVal !== 0 && !newVal) this.test1 = 0
},
test2: function (newVal, oldVal) {
if (newVal !== 0 && !newVal) this.test2 = 0
this.test2 = Number(this.test2)
}
},
methods: {
updateTest2: function (e) {
this.test2 = e.target.value
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<div id="app">
<div class="container">
Directly assign 0 when empty: <input v-model.number="test1" type="number">
<pre>Test: {{test1}}</pre>
Assign 0 if input is empty when loses focus:<input :value="test2" @change="updateTest2($event)" type="number">
<pre>Test: {{test2}}</pre>
</div>
</div>
Upvotes: 1