Reactive does not work on data getter
Version
3.2.11
Reproduction link
Steps to reproduce
Open link
What is expected?
Vue render hi, 1
What is actually happening?
Vue is rendering hi, null
I have data like this:
const form = {
value: null,
props: {
get test() {
return `hi, ${form.value}`;
}
}
}
The form.props.test
property is a getter and is using the form.value
.
In template, I render: {{ form.props.test }}
.
In the mounted
hook, I do form.props.test = 1
. What is expected here is the template should render: hi, 1
This issue does not occur in Vue 2: https://codepen.io/hqnan/pen/GREmVqa
Vue 3 uses proxies for reactivity, where changes made directly to the original object are not observed.
You have a hard reference to the original, non-reactive plain form
object in the getter, so reading the getter will not result in registering form
as a reactive dependency - because it's a plain object.
Working version:
import { ref, reactive } from "vue";
export default {
data() {
const form = reactive({
value: null,
props: {
get test() {
return `hi, ${form.value}`;
}
}
});
return {
form
};
},
Note that this would not be the case if your getter used this
in reference to the object the getter is defined in - that would be reactive.
I'll close this as there's no way to cover this automatically, you have to use reactive()
here explicitly.
Thanks, @LinusBorg 💕
But how can I use this
in a nested object?
{
value: null,
props: {
get test() {
return `hi, ${this.value}`;
}
}
}
this.value
will be undefined
You can't, that's not what I meant.
In my experience, getters are just often used to refer to the same object they are defined on - and I wanted to make clear that in this common scenario, where you can use this
, it just works.