在嵌套 getter/setter 中访问顶级 Vue 数据

Accessing top-level Vue data in nested getter/setter

<template>
  <div id="app">
    {{ foo.bar }}
    <button @click="meaning++">click</button> <!--not reactive-->
    <button @click="foo.bar++">click2</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class App extends Vue {
  private meaning = 42;

  private foo = {
    that:this,
    get bar() {
      return this.that.meaning;
    },
    set bar(value) {
      this.that.meaning = value;
    },
  };

  created() {
    console.log(this); // VueComponent {}
    console.log(this.foo.that); // App {}
    console.log(this === this.foo.that); // false
  }
}
</script>

我希望 foo.bar 得到 meaning 的支持,这是一个顶级数据字段。我从上面的 hack 开始,将 this(Vue 选项实例)保存在 that 中,但我也知道在 运行 时,this 成为 VueComponent 实例在组件方法中,因此 this.meaning 不是 this.foo.that.meaning.

另一个问题是上面的代码片段会在 Chrome 中破坏 vue-devtoolsvue-devtools 将尝试在 instance._data 上调用 Object.keys(),即 null

foo.bar 得到 meaning 支持的正确方法是什么?我可能在那些 getter 和 setter.

中有任意复杂的逻辑

编辑:

由于 this 到 VueComponent 只能在 运行 时解析,我想到了这个有点 hackish 的解决方法:

<template>
  <div id="app">
    {{ foo.bar }} 
    <button @click="meaning++">click</button>  <!-- reactive now! -->
    <button @click="foo.bar++">click2</button>
  </div>
</template>

<script lang="ts">
import { Component, Vue } from "vue-property-decorator";

@Component
export default class App extends Vue {
  private meaning = 42;

  private foo = {
    that: {meaning:42} as any, // put exactly the same literal initail value here
    get bar() {
        return this.that.meaning;
    },
    set bar(value) {
      this.that.meaning = value;
    },
  };

  created() {
    this.foo.that = this;
    console.log(this); // VueComponent
    console.log(this.foo.that); // VueComponent
    console.log(this === this.foo.that); // true
  }
}
</script>

原回答:

对于任何面临同样问题的人,我得出的结论是

it's impossible to refer to outer-level data in inner-level object data in the Vue option instance.

因为VueComponent实例只能在运行的时候抓取,但是你必须在Vue configclass的构造函数中绑定that:this,这是在实例化之前的 VueComponent。因此 Vue 的响应式系统将没有任何机会更正 that.

中的引用

所以答案(对我来说)就是不要这样做。依赖项必须始终高于(或处于相同级别)依赖项,并且您不能将 foo 作为 bar 的命名空间。

bar 提升到最高级别。