<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> Quiero que foo.bar esté respaldado por el meaning de que es un campo de datos de nivel superior. Comienzo con el truco anterior para guardar this (la instancia de la opción Vue) en that , pero también soy consciente de que en el tiempo de ejecución, this se convierte en la instancia de VueComponent en los métodos de componentes, por lo tanto, este significado no es this.meaning this.foo.that.meaning
Un problema adicional es que el fragmento de código anterior romperá vue-devtools dentro de Chrome. vue-devtools intentará invocar Object.keys() en instance._data que es null .
¿Cuál es la forma correcta de hacer que foo.bar esté respaldado por meaning ? Podría estar teniendo una lógica arbitrariamente complicada en esos getter y setter.
Editar:
Dado que this para VueComponent solo se puede resolver en el tiempo de ejecución, llegué a esta solución un poco pirateada:
<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>es imposible hacer referencia a datos de nivel externo en datos de objetos de nivel interno en la instancia de la opción Vue.
Debido a que la instancia de VueComponent solo se puede capturar en tiempo de ejecución, pero debe vincular that:this en el constructor de la clase de configuración de Vue, que es anterior a la creación de instancias de VueComponent. Por lo tanto, el sistema reactivo de Vue no tendrá ninguna posibilidad de corregir la referencia en that archivo .
Así que la respuesta (para mí) es simplemente no hagas esto. Dependent siempre debe ser mayor que (o en el mismo nivel) que la dependencia, y no puede tener foo como espacio de nombres de bar .
Eleve la bar al nivel superior.