In my application I need to use a nested v-for to display a list of elements with a select-option.. This is the scenario
<div class="stuck" v-for="box in items">
<p>Pick an option for this box:</p>
<select v-model="box">
<option v-for="package in packages"
:value="package.id">{{ package.name }} </option>
</select>
</div>
The variable items come from Vuex store. In this way, i'm getting the error:
You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-model on an object property instead.
With this in mind, i'm going to change the code like so:
<div class="stuck" v-for="box in items">
<p>Pick an option for this box:</p>
<select v-model="box.id">
<option v-for="package in packages"
:value="package.id">{{ package.name }} </option>
</select>
</div>
I've just changed the select v-model
from the alias box, to the right id: box.id
In this way, all works... or... half works. Because, if i'm going to pick an option from the select, i got another error:
[vuex] Do not mutate vuex store state outside mutation handlers.
This is correct, because the v-model
is bind to box.id (that is not an alias but a real value). But, when i pick an option the v-model "try" to change box.id that come from Vuex store.
Now, in a simple scenario i will create a computed property for set/get to avoid vuex store mutation.
But... here i have a nested loop, so i cant create a computed on 'box.id'.
Do you have a solution for this ?
Thanks a lot!
you could try a different data flow pattern. Your select listens to the store (but does not directly update it)
<div class="stuck" v-for="box in items">
<p>Pick an option for this box:</p>
<select :value="box.id" @change="updateBox">
<option v-for="package in packages" :value="package.id">
{{ package.name }}
</option>
</select>
</div>
Then you create a method that fires whenever the selected option changes
updateBox(e) {
const id = e.target.value;
this.$store.commit('changeYourBox', id);
},
This function should commit a vuex mutation that alteres the box id. So you'd need that mutation too.
Once the store value updates, your components box
object updates and the select that listens to that store will update it's selected value accordingly.
That way, you can alter the store value from anywhere and the selected value will change as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With