Cuando creo una ref a partir de un objeto vacío y luego agrego propiedades del objeto, no hay reactividad:
<template> <p>{{hello}}</p> <button @click="add()">Click me</button> </template> <script> import {ref} from 'vue'; export default { name: "Test", setup(){ const myData = ref({}); return {myData} }, methods: { add(){ this.myData["text"] = "Hello"; console.log(this.myData); } }, computed: { hello(){ if(this.myData.hasOwnProperty("text")) return this.myData["text"]; return "no text"; } } } </script> Al hacer clic en el botón, se muestra que myData ha cambiado, pero la propiedad calculada hello no se actualiza.
También probé reactive({}) en lugar de ref({}) sin éxito.
Lo que funciona es esto const myData = ref({"text": "no text"}); . Pero, ¿por qué el objeto vacío no funciona?
Intenta actualizar tu objeto ref como
this.myData = {"text": "Hello"} const { ref, computed } = Vue const app = Vue.createApp({ /*setup(){ const myData = ref({}); const hello = computed(() => myData.value.hasOwnProperty("text") ? myData.value.text : myData.value = "no text") const add = () => { if(Object.keys(myData.value).length === 0) { myData.value = {'text': "Hello"}; } else { myData.value.otherProperty = "Hello again" } } return { myData, add, hello } },*/ setup(){ const myData = ref({}); return { myData } }, methods: { add(){ if(Object.keys(this.myData).length === 0) { this.myData = {"text": "Hello"} } else { this.myData.otherProperty = "Hello again" } console.log(this.myData) }, }, computed: { hello(){ return Object.keys(this.myData).length !== 0 ? this.myData[Object.keys(this.myData)[Object.keys(this.myData).length - 1]] : "no text" } } }) app.mount('#demo') <script src="https://unpkg.com/vue@3.2.29/dist/vue.global.prod.js"></script> <div id="demo"> <p>{{ hello }}</p> <button @click="add">Click me 2 times</button> </div>Si cambia su propiedad calculada para que se defina de manera que haga referencia a myData['text'] directamente antes de regresar, las cosas funcionan como se esperaba:
computed: { hello() { return this.myData['text'] || 'no text'; // works } Sospecho que lo que sucede con su código original es que el código de seguimiento de dependencias de Vue no puede ver que su función depende de myData . Considere que hello está siendo llamado (por Vue) antes de que exista la propiedad de text en el objeto. En ese caso, la función regresa antes de tocar el valor proxy (hace un cortocircuito tan pronto como ve que hasOwnProperty ha regresado falso).
El seguimiento de dependencias en Vue se realiza dinámicamente , por lo que si su propiedad calculada no toca ninguna variable reactiva cuando se llama, Vue no considera que tenga dependencias externas, por lo que no se molestará en llamarla en el futuro. Simplemente usará el valor previamente almacenado en caché para las llamadas posteriores.