MongoLato
MongoLato

Reputation: 381

Data is not updated when using as object, but changes normally when it's a variable

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.

Upvotes: 1

Views: 69

Answers (2)

Sergey
Sergey

Reputation: 309

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]};
}

Upvotes: 0

Riddhi
Riddhi

Reputation: 2244

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])
}

Upvotes: 1

Related Questions