Currently, I have a VueJS app where you can click a button to create a set of two inputs. These two inputs perform a simple math function on key up. These math functions work with one set of inputs. However, since I'm using document.getElementById to grab the inputs, it will only work on the first set of inputs. Is there any way I can uniquely identify each set of inputs so I can perform this math function individually?
Example:
Vueponent('product', {
template: `
<div>
<select>
<option>Product One</option>
<option>Product Two</option>
</select>
<input class="input" id="bags" @keyup="$emit('calculatevolume')" type="number" placeholder="Bags">
<input class="input" id="volume" @keyup="$emit('calculatebags')" type="number" placeholder="Volume">
<button @click="$emit('remove')">Delete</button>
</div>
`
})
new Vue({
el: '#app',
data: {
index: 0,
products: []
},
methods: {
addProduct: function() {
this.products.push(this.index);
this.index++;
},
calculatevolume: function() {
var inputs = document.querySelectorAll(".input");
var bags = document.getElementById("bags");
var volume = document.getElementById("volume");
volume.value = bags.value * 25;
},
calculatebags: function() {
var inputs = document.querySelectorAll(".input");
var bags = document.getElementById("bags");
var volume = document.getElementById("volume");
bags.value = volume.value / 25;
}
}
})
<script src=".2.6/vue.min.js"></script>
<div id="app">
<button
v-model="index"
v-on:click="addProduct"
placeholder="Add Product">Add Product</button>
<div class="products">
<div
is="product"
v-for="(product, index) in products"
:id="index"
:key="product"
@remove="products.splice(index, 1)"
@calculatevolume="calculatevolume"
@calculatebags="calculatebags">
</div>
</div>
</div>
Currently, I have a VueJS app where you can click a button to create a set of two inputs. These two inputs perform a simple math function on key up. These math functions work with one set of inputs. However, since I'm using document.getElementById to grab the inputs, it will only work on the first set of inputs. Is there any way I can uniquely identify each set of inputs so I can perform this math function individually?
Example:
Vue.ponent('product', {
template: `
<div>
<select>
<option>Product One</option>
<option>Product Two</option>
</select>
<input class="input" id="bags" @keyup="$emit('calculatevolume')" type="number" placeholder="Bags">
<input class="input" id="volume" @keyup="$emit('calculatebags')" type="number" placeholder="Volume">
<button @click="$emit('remove')">Delete</button>
</div>
`
})
new Vue({
el: '#app',
data: {
index: 0,
products: []
},
methods: {
addProduct: function() {
this.products.push(this.index);
this.index++;
},
calculatevolume: function() {
var inputs = document.querySelectorAll(".input");
var bags = document.getElementById("bags");
var volume = document.getElementById("volume");
volume.value = bags.value * 25;
},
calculatebags: function() {
var inputs = document.querySelectorAll(".input");
var bags = document.getElementById("bags");
var volume = document.getElementById("volume");
bags.value = volume.value / 25;
}
}
})
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
<button
v-model="index"
v-on:click="addProduct"
placeholder="Add Product">Add Product</button>
<div class="products">
<div
is="product"
v-for="(product, index) in products"
:id="index"
:key="product"
@remove="products.splice(index, 1)"
@calculatevolume="calculatevolume"
@calculatebags="calculatebags">
</div>
</div>
</div>
Share
Improve this question
asked Apr 11, 2017 at 20:20
nicholasdrzewieckinicholasdrzewiecki
1212 gold badges4 silver badges9 bronze badges
2
- Why don't you use v-model on your input fields instead? – Egor Stambakio Commented Apr 11, 2017 at 20:39
- I just read that in the documentation. Definitely looks like a step in the right direction. I also don't think I'm supposed to grab elements by their id, let alone create the same variables twice for two different methods. That was more for testing purposes as I couldn't get global variables to work. – nicholasdrzewiecki Commented Apr 11, 2017 at 20:43
1 Answer
Reset to default 5With Vue, you generally do not want or need to be manipulating the DOM yourself in any way.
To that end, I moved the calculation of bags
and volume
into your ponent. Using v-model
, they will always reflect the value in data. Additionally, I added watchers to their values so you could change the opposite number when they change.
Vue.ponent('product', {
template: `
<div>
<select>
<option>Product One</option>
<option>Product Two</option>
</select>
<input class="input" id="bags" v-model="bags" type="number" placeholder="Bags">
<input class="input" id="volume" v-model="volume" type="number" placeholder="Volume">
<button @click="$emit('remove')">Delete</button>
</div>
`,
data(){
return {
bags: null,
volume: null
}
},
watch:{
bags(newVal){
this.volume = newVal * 25
},
volume(newVal){
this.bags = newVal / 25
}
}
})
new Vue({
el: '#app',
data: {
products: []
},
methods: {
addProduct: function() {
this.products.push(this.index);
},
}
})
And the new template
<div id="app">
<button
v-on:click="addProduct"
placeholder="Add Product">Add Product</button>
<div class="products">
<div
is="product"
v-for="(product, index) in products"
:id="index"
:key="product"
@remove="products.splice(index, 1)"
>
</div>
</div>
</div>
Example.