First of all, I love Vue 3. I really enjoy it over many other frameworks. But I think I have found a limitation. I am trying to wrap some of my very complicated logic in class
where internally each instance does the dirty work. This feels more natural for me. But when my instances are wrapped with reactive()
, everything seems to break.
Here is an example:
export class Container {
public stat: Ref<Stat> = ref({ cpu: 0 });
private _throttledStatHistory: UseThrottledRefHistoryReturn<Stat, Stat>;
constructor(
public readonly id: string,
// more fields not shown...
) {
this._throttledStatHistory = useThrottledRefHistory(this._stat, { capacity: 300, deep: true, throttle: 1000 });
}
public statHistory: ComputedRef<UseRefHistoryRecord<Stat>[]> = computed(
() => this._throttledStatHistory.history.value
);
}
I can use this object with something like
const container = new Container("123")
container.stat.value = { cpu: 1}
container.stat.value = { cpu: 2}
However, when using reactive like so:
const myRef = reactive(new Container("123"))
Everything seems to break:
myRef.value.stat.value // stat is no longer a ref. It is now a proxy
myRef.value.stat.value = {cpu: 3} // also breaks as statHistory is not updated at all
My assumption is that everything being wrapped in reactive
breaks.
Somethings can be fixed with toRaw()
like toRaw(myRef.value).stat.value = ...
but that feels unnatural.
Note if I make stat
private with private stat: Ref<Stat> = ref({ cpu: 0 });
then the problem still persists. I expected private members to not be affected by reactive
.
I am going crazy debugging this. What is the proper way to do class with internal reactivity?
Thanks!
ref(new Container("123"))
- can be solved with shallowRef, but this is just a symptom of a bigger problem – Paramorphismstat
to outside. – Showcomputed
. Still didn't work. But reading the doc I found that it is documented forreactive
to unwrap all refs. That's good to see. Then I sawshallowRef
as you suggested andmarkRaw
. I am going to play with those. – Show