I have a list of checkboxes that are rendered with a v-for
on a component. When checked, the checkboxes fill up an array with currently selected checkboxes. The problem comes when one or more of the checked checkboxes is removed - the v-model
still counts the removed checkbox. How do I update the v-model
as my array updates? I tried force re-rendering the whole component which solves the problem but it's not the solution I need.
<div v-for="player in players" :key="player.id">
<input
v-model="selectedPlayers"
:value="player.id"
type="checkbox"
:id="player.id"
/>
<label :for="player.id">
{{ player.name }}
</label>
</div>
Desired outcome
CodePudding user response:
V-model won't remove data when the component is no longer rendered, you need to do that explicitly.
You could filter selectedPlayers from the @click handler so that it only includes ids that are in the new variable.
this.selectedPlayers = this.selectedPlayers.filter(
id => players2.find(
player => player.id === id
)
)
CodePudding user response:
So from what I understand, you have this player2
array, that you need to compare against. Whatever is there in the players2
array needs to be there in the selectedPlayers
array. To do this just use the use map
array function to iterate over the players2
array to return only the ids
of the players and then store them in the selected players array which being a reactive property will automatically patch the DOM
. There's absolutely no need to re-render the component.
Vue.config.productionTip = false;
Vue.config.devtools = false;
new Vue({
el: "#app",
data() {
return {
selectedPlayers: [],
players: [
{name: "Arnold",id: "1"},
{name: "Rambo",id: 2},
{name: "Terminator",id: 3},
{name: "Titan",id: 4},
{name: "Odin",id: 5},
],
players2: [
{name: "Titan",id: 4},
{name: "Odin",id: 5},
],
};
},
methods: {
clicked() {
this.players = this.players2;
this.selectedPlayers = this.players2.map(p => p.id);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
If you check all checkboxes and press the button, the array still contains all elements
<div v-for="player in players" :key="player.id">
<input v-model="selectedPlayers" :key="players.length" :value="player.id" type="checkbox" :id="player.id" />
<label :for="player.id">
{{ player.name }}
</label>
</div>
{{ selectedPlayers }}
<button @click="clicked">Press me</button>
</div>