When I create a ref
from an empty object and later add object properties, there is no reactivity:
<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(){
return this.myData.hasOwnProperty("text")) ? this.myData["text"] : "no text";
}
}
}
</script>
Clicking the button shows that myData
has changed but the computed property hello
does not update.
Also tried reactive({})
instead of ref({})
without success.
It works when we initialize the ref with properties, like const myData = ref({"text": "no text"});
.
But why does the empty object not work?
EDIT:
Finally found out what exactly the problem is and how it can be solved:
The reactivity core of Vue3 is not alert of Object.keys()
but only of the values of the properties, and the empty object does not have any. However, you can make Vue3 alert, if the computed property is defined like
computed: {
hello(){
return Object.keys(this.myData).indexOf("text") > -1 ? this.myData["text"] : "no text";
}
The call to Object.keys(this.myData)
is needed to make the reactivity system aware of what we are interested in. This is similar to setting a watch
on Object.keys(this.myData)
instead of watching this.myData
.