0
<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

一个额外的问题是上面的代码片段会vue-devtools在 Chrome 内部中断。vue-devtools将尝试调用Object.keys()which instance._datais null

foo.bar得到支持的正确方法是meaning什么?我可能在那些 getter 和 setter 中有任意复杂的逻辑。

4

1 回答 1

0

编辑:

由于thisVueComponent 只能在运行时解决,所以我找到了这种 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>

原答案:

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

Vue 选项实例中的内层对象数据中无法引用外层数据。

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

所以答案(对我来说)就是不要这样做。Dependent 必须始终高于(或等于)依赖项,并且您不能拥有fooasbar的命名空间。

提升bar到最高水平。

于 2022-01-07T16:24:09.427 回答