[reactive] Add a way to bi-direction detect changes of original object
Version
3.0.11
Reproduction link
https://codesandbox.io/s/reverent-lewin-zs1qu?file=/src/App.vue
Steps to reproduce
There's no way to notify that the original object has been changed. So this code won't work.
<template>
<div>{{ foo.description }}</div>
</template>
<script>
import { reactive } from "vue";
export default {
name: "App",
setup() {
return { foo: reactive(new Foo()) };
},
};
class Foo {
constructor() {
this.description = "placeholder description";
setTimeout(() => {
// this won't trigger the DOM to be updated
this.description = "my description";
}, 100);
}
}
</script>
What is actually happening?
Like I showed in the example code, I can't find a workaround for this😢
We are using Proxies to detect changes, the original object stays untouched. This is by design, and there will be no way to achieve what you want.
We realize that this leads to a few caveats when using reactivity with classes, such as the one you demonstrated, but that's the way it is.
Generally, we have always recommended to use plain objects with reactivity and keep classes out of it.
@LinusBorg I could go with a workaround by doing this: https://codesandbox.io/s/stupefied-wave-ti0bb?file=/src/index.ts
but this time, the typing of reactive
won't work properly in ts...
why would you make the instance reactive()
if it already uses ref()
internally (which are reactive)?
Just don't replace the refs, just set their value:
get url(): string {
return this._url.value;
}
set url(newUrl: string) {
this._url.value = newUrl;
}
@LinusBorg
why would you make the instance reactive() if it already uses ref() internally (which are reactive)?
oh, because we could have any other public properties on the class instance (I have edited the example code a bit).
Just don't replace the refs, just set their value:
Because I want to init the instance property(url
this case) asynchronously once if I initialized the class.