vuejs / core

🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
https://vuejs.org/
MIT License
46.71k stars 8.19k forks source link

mismatched child nodes count in `patchBlockChildren` when rendering component returning render function in JSX from `computed()` with `<slot v-if="ref">` #10319

Open n0099 opened 7 months ago

n0099 commented 7 months ago

Vue version

3.4.18

Link to minimal reproduction

https://stackblitz.com/edit/vitejs-vite-cs8k7r?file=src%2FScopedSlots.vue%2Csrc%2FApp.vue

Steps to reproduce

Click the Toggle flag button.

What is expected?

No exception was thrown.

What is actually happening?

TypeError: Cannot read properties of undefined (reading 'el')
    at patchBlockChildren (chunk-EVMNRHZZ.js?v=f93e5a51:7163:18)
    at processFragment (chunk-EVMNRHZZ.js?v=f93e5a51:7266:9)
    at patch (chunk-EVMNRHZZ.js?v=f93e5a51:6758:9)
    at ReactiveEffect.componentUpdateFn [as fn] (chunk-EVMNRHZZ.js?v=f93e5a51:7542:9)
    at ReactiveEffect.run (chunk-EVMNRHZZ.js?v=f93e5a51:227:19)
    at instance.update (chunk-EVMNRHZZ.js?v=f93e5a51:7586:17)
    at callWithErrorHandling (chunk-EVMNRHZZ.js?v=f93e5a51:1667:32)
    at flushJobs (chunk-EVMNRHZZ.js?v=f93e5a51:1874:9)

System Info

No response

Any additional comments?

By adding a breakpoint just before the exception was thrown: https://github.com/vuejs/core/blob/3f92126a26a544dfa69211cf2977556a2706bb2c/packages/runtime-core/src/renderer.ts#L968, we can see the length of two children params is mismatched, oldChildren.length will always be less one than the newChildren.length: image

The <FontAwesomeIcon> is returning a render function h() within computed() to dynamically build elements by the component props: https://github.com/FortAwesome/vue-fontawesome/blob/560b07aade4b8b1f909b448391968935ff9a759c/src/components/FontAwesomeIcon.js#L175 https://github.com/FortAwesome/vue-fontawesome/blob/560b07aade4b8b1f909b448391968935ff9a759c/index.js#L296 https://github.com/FortAwesome/vue-fontawesome/blob/560b07aade4b8b1f909b448391968935ff9a759c/index.js#L329-L337

The following approaches will prevent this exception:

edison1105 commented 7 months ago

duplicated of #9308