【问题标题】:Vuejs Es6 class reactivityVuejs Es6 类反应性
【发布时间】:2018-09-11 01:18:58
【问题描述】:

我正在尝试将 vuejs 中的计算属性关联到 es6 类。 我的 Vue 实例如下所示:

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

我的班级是这样的

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

如果我尝试做这样的事情:

this.localClass.selected = true

但是 setter 永远不会被调用,就像失去了反应性一样,我不明白为什么。

我也试试:

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

我将 customClass 作为道具传递,但即使直接在组件中创建新实例也不会改变结果。

在 vuejs 文档中,我不记得有一节讨论过 es6 类中的反应性问题,所以我想知道是否有人知道为什么以及如何使我的类具有反应性。

提前致谢

【问题讨论】:

  • 您没有设置localClass,这会激活setter,您设置的是localClass的成员,但不会。

标签: javascript vue.js ecmascript-6 es6-class vue-reactivity


【解决方案1】:

计算属性的设置器,例如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>

【讨论】:

    猜你喜欢
    • 2020-01-31
    • 2015-06-08
    • 2019-10-18
    • 2017-09-30
    • 1970-01-01
    • 2019-07-21
    • 2018-07-20
    • 2019-06-22
    相关资源
    最近更新 更多