1

I'm writing a function to update a custom checkbox when clicked (and I don't want to use native checkbox for some reasons).

The code for checkbox is

<div class="tick-box" :class="{ tick: isTicked }" @click="() => isTicked = !isTicked"></div>

which works find.

However, there are so many checkboxes, so I use object to keep track for each item. It looks like this

<!-- (inside v-for) -->
<div class="tick-box" :class="{ tick: isTicked['lyr'+layer.lyr_id] }" @click="() => {
  isTicked['lyr'+layer.lyr_id] = !isTicked['lyr'+layer.lyr_id]
}"></div>

Now nothing happens, no error at all.

When I want to see isTicked value with {{ isTicked }}, it's just shows {}.

This is what I define in the <script></script> part.

export default {
  data() {
    return {
      isTicked: {},
      ...
    };
  },
  ...
}

Could you help me where I get it wrong?

Thanks!

Edit:

I know that declaring as isTicked: {}, the first few clicks won't do anything because its proerty is undefined. However, it should be defined by the first/second click not something like this.

Bernhard
  • 4,855
  • 5
  • 39
  • 70
MongoLato
  • 351
  • 2
  • 20
  • I think it might work better to use an array with `ticked` values, and then use `v-for` to render all the checkboxes. – Kokodoko Jan 28 '19 at 10:17
  • Read for object change detection: https://vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats – patapity Jan 28 '19 at 20:01

2 Answers2

1

Objects does not reflect the changes when updated like this. You should use $set to set object properties in order to make them reactive. Try as below

   <div class="tick-box" :class="{ tick: isTicked['lyr'+layer.lyr_id] }" @click="onChecked"></div>

Add below method:

onChecked() {
  this.$set(this.isTicked,'lyr'+this.layer.lyr_id, !this.isTicked['lyr'+this.layer.lyr_id])
}
Riddhi
  • 2,174
  • 1
  • 9
  • 17
  • Thanks! This helped me. I modified this to oncheck(lyr_id) and use that in the function instead, i.e., `this.$set(this.isTicked,'lyr'+lyr_id, !this.isTicked['lyr'+lyr_id])` since `this.layer` is not in the scope. – MongoLato Jan 29 '19 at 05:48
0

VueJS watches data by reference so to update object in state you need create new one.

onChecked(lyr_id) {
    const key = 'lyr'+lyr_id;
    this.isTicked = {...this.isTicked, [key]: !this.isTicked[key]};
}

Sergey
  • 301
  • 4
  • 6