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
Advertisement
Answer
The setter of a computed property, say myComputedProperty
, is triggered when you assign to that property (e.g. 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>