script setup: Compiler creates wrong patch flags depending on style of variable assignment.
Version
3.0.5
Reproduction link
https://github.com/Aubyn/issue-vue3-reactive-array.git
Steps to reproduce
- clone, run
yarn
andyarn dev
in terminal - use
assignment 2
to create reactive array, named asreceivedData
inApp.vue
- click
emit
button on the page - DOM view didn't update(
why
) asreceivedData
updated - use
assignment 1
- click
emit
button - DOM view updates as
receivedData
updated(why
)
/* assignment 1 */
const { receivedData, receiveHandler } = {
receivedData: reactive([]),
receiveHandler: function (arg1, arg2) {
receivedData.push([arg1, arg2]);
}
};
/* assignment 2 */
const receivedData = reactive([]);
const receiveHandler = function (arg1, arg2) {
receivedData.push([arg1, arg2]);
};
What is expected?
assignment 1
and assignment 2
trigger DOM update.
What is actually happening?
assignment 1
did trigger DOM update, but assignment 2
didn't.
The issue isn't really the reactivity of the array, as the child does correctly update hwne the array is changed - can be verified by loggind to console in onUpdated()
.
Rather, the generated render function is buggy - it adds a patch flag that seems to make the child component skip the update of that node, even though it's necessary.
// with assignment 1:
_createVNode("p", null, "emit in slot: " + _toDisplayString($setup.receivedData), 1 /* TEXT */)
// with assignment 2:
_createVNode("p", null, "emit in slot: " + _toDisplayString($setup.receivedData))
it's also limited to the experimental <script setup>
implementation.
After converting App.vue
to a normal script
code, both assignment variations work the same.
Thanks, I'll use assignment 1
now, as it meets logical concerns of Composition API in <script setup>
and perform expectedly.
"bindings": {
"VueNext": "setup-const",
"ref": "setup-const",
"reactive": "setup-const",
"provide": "setup-const",
"watchEffect": "setup-const",
"cars": "setup-const",
"pens": "setup-const",
"receivedData": "setup-const", // Caused by here
"receiveHandler": "setup-const"
},
The receivedData
is treated as a setup-const
, which will cause patching to be skipped.