Subscribe on changes!

script setup: Compiler creates wrong patch flags depending on style of variable assignment.

avatar
Jan 8th 2021

Version

3.0.5

Reproduction link

https://github.com/Aubyn/issue-vue3-reactive-array.git

Steps to reproduce

  1. clone, run yarn and yarn dev in terminal
  2. use assignment 2 to create reactive array, named as receivedData in App.vue
  3. click emit button on the page
  4. DOM view didn't update(why) as receivedData updated
  5. use assignment 1
  6. click emit button
  7. 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.

avatar
Jan 9th 2021

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.

avatar
Jan 9th 2021

Thanks, I'll use assignment 1 now, as it meets logical concerns of Composition API in <script setup> and perform expectedly.

avatar
Jan 9th 2021
"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.