Reputation: 1748
I'm trying to essentially create a two-way calculator and I've chosen to use inches to millimeters as an example.
See the sandbox here: https://q8y4s.csb.app/
<template>
<div>
<input type="number" v-model="inches" placeholder="Inches" />
<br />
<input type="number" v-model="mm" placeholder="Millimeters" />
</div>
</template>
<script>
export default {
data() {
return {
inches: "",
mm: "",
};
},
watch: {
inches: function (newVal) {
this.mm = newVal * 25.4;
},
mm: function (newVal) {
this.inches = newVal / 25.4;
},
},
};
</script>
The issue is going from millimeters to inches. I'm not entirely sure what's happening but it seems like a feedback loop of some sort. I know I can use computed to achieve this particular functionality but I'd prefer to use watchers since there is more logic to the 'watched' fields in my project.
This tutorial uses meters to kilometers and accomplishes the same thing but I'm uncertain why millimeters to inches creates the 'feedback loop' effect
Upvotes: 2
Views: 1762
Reputation: 1
I was searching this for long time now. I am new to vue but the following solution worker for me it is in vue3
<template>
<input type="number" @input = "changetag('1')" v-model.number="state.unit1" placeholder="-">
<input type="number" @input = "changetag('2')" v-model.number="state.unit2" placeholder="-">
<input type="number" @input = "changetag('3')" v-model.number="state.unit3" placeholder="-">
</template>
<script>
import { reactive } from 'vue';
export default {
setup() {
const state = reactive({
tag: '',
unit1: null,
unit2: null,
unit3: null,
});
function changetag(value){
state.tag = value;
if (value =='2')
state.unit1 = state.unit2/2
if (value =='3')
state.unit1 = state.unit3/3
updatevalue(value)
}
function updatevalue(value){
if (value!='2')
state.unit2 = state.unit1*2
if (value!='3')
state.unit3 = state.unit1*3
}
return{
state,
changetag,
updatevalue,
}
}
}
</script>
feild2 = 2 times field1 & field3 = 3 times field
Upvotes: 0
Reputation: 1857
What you could do is create a safety valve to prevent the recursion. Something like:
export default {
data() {
return {
isChangingMm: false,
isChangingInches: false,
// others
}
},
watch: {
inches: function (newVal) {
if (!this.isChangingMm) {
this.isChangingInches = true
this.mm = newVal * 25.4
this.isChangingInches = false
}
},
mm: function (newVal) {
if (!this.isChangingInches) {
this.isChangingMm = true
this.inches = newVal / 25.4
this.isChangingMm = false
}
}
},
}
Upvotes: 2