In accordance with the official documentation, it is necessary to use ref
or reactive
when defining the "data" variable in the new composition api setup
method. This allows Vue to track any changes made to that particular variable.
While experimenting with reactivity, I observed a peculiar behavior. Consider the following component as a reference:
App.vue
<template>
<div id="app">
<p>{{ awesomeState.txt }}</p>
<p>{{ myConst }}</p>
<button @click="operate">Test it</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import awesomeStore from "@/AwesomeStore";
export default defineComponent({
setup() {
const awesomeState = awesomeStore.getState();
const myConst = "I'm a const"; // To maintain reactivity, should be declared as `const myConst = ref('...');`
return {
awesomeState,
myConst
};
},
name: "App",
methods: {
operate() {
this.myConst = 'Why does this update?';
awesomeStore.changeText("yess!");
}
}
});
</script>
AwesomeStore.ts
import { reactive, readonly, watch } from "vue";
export abstract class Store<T extends Record<string, any>> {
protected state: T;
constructor() {
const data = this.data();
this.state = reactive(data) as T;
watch(() => this.state, (value) => {
console.log(value); debugger;
}, {deep: true});
}
protected abstract data(): T;
public getState(): T {
return readonly(this.state) as T;
}
}
interface Test extends Object {
txt: string;
}
class AwesomeClass extends Store<Test> {
protected data(): Test {
return {
txt: "init"
};
}
public changeText(msg: string) {
this.state.txt = msg;
}
}
export default new AwesomeClass();
Upon clicking the button, the myConst
property is updated.
One thing to note is that methods should not be defined outside the setup()
scope. The reason behind this unexpected behavior eludes me.
Any suggestions on why this might be happening?
Thank you for your assistance,
UPDATE
I failed to mention that this behavior only occurs if I try to modify the constant at the same time as invoking the awesomeStore.changeText
method:
operate() {
this.myConst = 'Why does this update?';
//awesomeStore.changeText("yess!"); <-- If commented out, myConst remains unchanged.
}