<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>
I want foo.bar
to be backed by meaning
which is a top level data field. I start with the hack above to save this
(the Vue option instance) in that
, but I'm also aware that at run time, this
become the VueComponent instance in component methods, thus this.meaning
is not this.foo.that.meaning
.
An extra problem is that the code snippet above will break vue-devtools
inside Chrome. vue-devtools
will try invoke Object.keys()
on instance._data
which is null
.
What's the correct way to make foo.bar
be backed by meaning
? I might be having arbitrarily complicated logic in those getter and setter.
Edit:
Since this
to the VueComponent can only be resolved at runtime, I came to this kinda hackish workaround:
<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.
Because the VueComponent instance can only be grabbed at run time, but you have to bind that:this
in the constructor of the Vue config class, which is prior to the instantiation of VueComponent. Thus the reactive system of Vue won't have any chance to correct the reference in that
.
So the answer (for me) is simply don't do this. Dependent must always be higher than (or on the equal level of) the dependency, and you can't have foo
as bar
's namespace.
Elevate bar
to the top level.