简体   繁体   中英

Vuejs Es6 class reactivity

i'm trying to have a computed property in vuejs associated to a es6 class. My Vue instance looks like this:

...
props: ['customClass'],
computed: {
    localClass: {
         get() {
             return this.customClass
         },
         set (value) {
             console.log("changed")
         }
     }
 }
 ...

My class looks like this

class CustomClass {
    constructor () {
        this.selected = false
    }
}

If i try to do something like that:

this.localClass.selected = true

but the setter is never called, like the reactivity has been lost and i don't understand why.

I also try:

Vue.set(this.localClass, 'selected', true)

I pass customClass as a prop, but even creating a new instance directly in the component it doesn't change the result.

In vuejs docs i don't recall a section talking about reactivity problem in es6 class, so i was wondering if someone know why and how to make my class reactive.

Thanks in advance

The setter of a computed property, say myComputedProperty , is triggered when you assign to that property (eg this.myComputedProperty = {something: 'else'} .

What you probably are looking for is a watcher , more specifically, a watcher with deep: true , such as:

watch: {
  localClass: {
    deep: true,
    handler() {
      out.innerHTML += "watched!";
    }
  }
},

Demo below.

 class CustomClass { constructor() { this.selected = false } } Vue.component('custom', { template: '#custom', props: ['customClass'], computed: { localClass: { get() { return this.customClass }, set(value) { out.innerHTML += "changed!\n"; } } }, watch: { localClass: { deep: true, handler() { out.innerHTML += "watched!\n"; } } }, methods: { assignToSelected() { this.localClass.selected = true }, assignToLocalClass() { this.localClass = { selected: true } } } }); new Vue({ el: '#app', data: { test: new CustomClass() }, })
 #out { background: black; color: gray; } span { font-size: x-small; font-family: verdana }
 <script src="https://unpkg.com/vue"></script> <template id="custom"> <div> {{ localClass }} <br> <button @click="assignToSelected">assignToSelected</button> <span>Note: will trigger "watched!" just once, because, since the value is hardcoded in the method (see code) subsequent clicks won't modify the value.</span> <br><br> <button @click="assignToLocalClass">assignToLocalClass</button> <span>Note: assignToLocalClass() will trigger the computed setter, but wont trigger the watcher because the computed setter currently sets nothing, so nothing changed for the watcher to trigger.</span> </div> </template> <div id="app"> <custom :custom-class="test"></custom> </div> <pre id="out"></pre>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM