Can somebody explain to me why reactivity breaks for number
in this example:
https://codesandbox.io/s/vue-3-reactivity-issue-4rto59?file=/public/index.html
I have 2 composables (useNumber.js and useRandomNumber.js) which I both spread in the return of the setup()
function in my main.js
file.
The useNumber
composable functionality (adding 1 to number) is triggered from within setup()
.
The useRandomNumber
functionality (generating a random number) is triggered from within itself via setInterval
.
Both number.value
and randomNumber.value
are used inside index.html
but only randomNumber
remains reactive.
While both remain reactive inside setup()
.
Why does the spreading not break both variables but only on number
?
How my example works:
The randomNumber
is changing onscreen. So this is reactive.
The number
can be altered by clicking the ADD button. As you will see, the value changes in the console (as this is from within setup()
) but not on screen from the return
.
I'd expect that reactivity for both would work OR break due to the spreading.
You are adding a different number
ref to the template than the one in your script:
const { number, addOne } = useNumber(); // <--- creates a "number" ref
const addToNumber = () => {
addOne();
console.log("NUMBER", number.value);
};
return {
...useNumber(), // <--- creates another "number", the template works on that
...useRandomNumber(),
addToNumber // <--- works on a variable not used in the template
};
To fix it, just return the actual ref:
return {
...useRandomNumber(),
addToNumber, number
};
it also works if you keep it as it is, but call the addOne()
method associated with the number
:
<button @click="addOne()">Add</button>
(of course the addToNumber()
function is now unused)
If you want the number to be the same for each call to useNumber()
, like a global variable, you have to declare it outside the function:
import { ref } from "vue";
const number = ref(0); // <--- there can only be one
export function useNumber() {
const addOne = () => { // <--- could declare that outside as well
number.value++;
};
return {
number,
addOne
};
}