Vuejs Es6 class 反应性
Vuejs Es6 class reactivity
我正在尝试将 vuejs 中的计算 属性 关联到 es6 class。
我的 Vue 实例如下所示:
...
props: ['customClass'],
computed: {
localClass: {
get() {
return this.customClass
},
set (value) {
console.log("changed")
}
}
}
...
我的class看起来像这样
class CustomClass {
constructor () {
this.selected = false
}
}
如果我尝试这样做:
this.localClass.selected = true
但是 setter 从未被调用,就像反应性已经丢失,我不明白为什么。
我也试试:
Vue.set(this.localClass, 'selected', true)
我将 customClass 作为 prop 传递,但即使直接在组件中创建新实例也不会改变结果。
在 vuejs 文档中,我不记得讨论 es6 class 中反应性问题的部分,所以我想知道是否有人知道为什么以及如何使我的 class 反应性。
提前致谢
计算 属性 的 setter,比如 myComputedProperty
,当您分配给那个 属性 时触发(例如 this.myComputedProperty = {something: 'else'}
.
您可能正在寻找的是 watcher, more specifically, a watcher with deep: true
,例如:
watch: {
localClass: {
deep: true,
handler() {
out.innerHTML += "watched!";
}
}
},
下面的演示。
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>
我正在尝试将 vuejs 中的计算 属性 关联到 es6 class。 我的 Vue 实例如下所示:
...
props: ['customClass'],
computed: {
localClass: {
get() {
return this.customClass
},
set (value) {
console.log("changed")
}
}
}
...
我的class看起来像这样
class CustomClass {
constructor () {
this.selected = false
}
}
如果我尝试这样做:
this.localClass.selected = true
但是 setter 从未被调用,就像反应性已经丢失,我不明白为什么。
我也试试:
Vue.set(this.localClass, 'selected', true)
我将 customClass 作为 prop 传递,但即使直接在组件中创建新实例也不会改变结果。
在 vuejs 文档中,我不记得讨论 es6 class 中反应性问题的部分,所以我想知道是否有人知道为什么以及如何使我的 class 反应性。
提前致谢
计算 属性 的 setter,比如 myComputedProperty
,当您分配给那个 属性 时触发(例如 this.myComputedProperty = {something: 'else'}
.
您可能正在寻找的是 watcher, more specifically, a watcher with deep: true
,例如:
watch: {
localClass: {
deep: true,
handler() {
out.innerHTML += "watched!";
}
}
},
下面的演示。
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>