Reputation: 751
I'm having a weird behavior from the Vuetify componentv-checkbox
.
The codepen shows 3 checkboxes per array element. I want to read the actual state of the checkbox (true or false) near each checkbox.
Change the checkboxes's state and see it is being displayed correctly.
Then, remove the line {{ counter }}
and check again.
If you check a checkbox, it has to show 'true', and viceversa, if you uncheck it, it has to show 'false'. 'false' is the default value.
Actual Behavior
{{ counter }}
that I'm using for the number of checks/unchecks is being printed in HTML, the state of the checboxes are working showing correctly. If not, the states remains in the default value.(nevertheless, if I console.log it, they appear to be changed).This is my code: - HTML:
<div id="app">
<div v-for="(row, index) in rows" :key="index">
<v-layout row wrap>
{{ row.item }}:
<v-card flat v-for="(friend, idx) in row.friends" :key="`msg-${idx}`">
<v-checkbox
v-model="friend.selected"
:label="friend.name"
color="red"
hide-details
@click.native="counter++"
></v-checkbox>
{{ counter }}
{{ friend.selected }}
</v-card>
</v-layout>
<v-divider :key="`divider-${index}`"></v-divider>
</div>
</div>
new Vue({ el: "#app", data () { return { friendsAdded: ['Friend 1', 'Friend 2', 'Friend 3'], items: ['Place 1'], counter: 0, } }, methods: { updateStatus(friend) { // Do something later }, }, computed: { rows() { const rows = []; for(let i = 0; i < this.items.length; i += 1) { const row = {}; row.item = this.items[i]; row.friends = []; for(let j = 0; j < this.friendsAdded.length; j += 1) { const friend = {}; friend.name = this.friendsAdded[j]; friend.selected = false; row.friends.push(friend); }; rows.push(row); } console.log('rows: ', rows); return rows; } }, })
Here is codepen: https://codepen.io/rodrigoabb/pen/wYgzWW?editors=1010
Am I doing something obscenely wrong? How can I achieve the expected behavior without have to read that value (or something else)?
Thanks!
Upvotes: 1
Views: 2121
Reputation: 676
One thing is wrong with your approach:
You are trying (by using v-model
binded to friend.selected
, which gets and also sets value) to set value of a computed property (the rows
).
This is basically wrong: https://v2.vuejs.org/v2/guide/computed.html#Computed-Setter
What happens is:
The template was not sensitive to the change, although it actually occurs on the friends object. (Vuejs won't warn you about it because it is on a deep level of the computed object)
So, a re-render of your component never happened. But if that {{counter}}
exists, that {{counter}}
will be the sole reason for the re-render, which renders the whole template, including the {{friend.selected}}
With your simple case you can use the data
function to create the rows
array. Other options will be using separate data property to bind with the v-model
, which will then affect the main rows array with watcher (if needed) or to use computed setter.
data
:new Vue({
el: "#app",
data () {
let items = ['Place 1'];
let friendsAdded = ['Friend 1', 'Friend 2', 'Friend 3'];
const rows = [];
for(let i = 0; i < items.length; i += 1) {
const row = {};
row.item = items[i];
row.friends = [];
for(let j = 0; j < friendsAdded.length; j += 1) {
const friend = {};
friend.name = friendsAdded[j];
friend.selected = false;
row.friends.push(friend);
};
rows.push(row);
}
console.log('rows: ', rows);
return {
friendsAdded,
items,
counter: 0,
rows
}
},
methods: {
updateStatus(friend) {
// Do something later
},
},
})
Upvotes: 4