After moving an element to elsewhere in dom tree, the subsequent patching result seem to be affected. is this reasonable?
Vue version
3.3.4
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-prfqzh?file=src%2Fmain.js
Steps to reproduce
here is the simplified code:
// main.js
import { createApp, defineComponent, h, onMounted, ref, toRaw } from 'vue'
const prevData = [
{ name: 'child-1' },
{
name: 'parent', children: [
{ name: 'child-2' },
]
}
]
const nextData = [
{ name: 'child-1' },
{ name: 'child-2' },
]
const data = ref(prevData)
const Child = defineComponent({
name: 'Child',
props: {
name: String,
host: Object
},
setup(props) {
return () => h('div', { id: props.name }, [props.name])
}
})
const Parent = defineComponent({
name: 'Parent',
props: {
name: String
},
setup(props, { slots }) {
return () => h('div', { id: props.name }, [
props.name,
slots.default()
])
}
})
createApp({
name: "App",
setup() {
onMounted(() => {
setTimeout(() => {
/** in real scenario, it's drag and drop operation */
const child2 = document.querySelector(`#child-2`)
const container = document.querySelector('#container')
container.append(child2)
/** "nextData" may be fetched form the backend */
data.value = nextData
}, 1000)
})
return () => h('div', { id: "container" }, data.value.map((i) => {
if (!i.children) {
return h(Child, { key: i.name, name: i.name })
}
return h(Parent, { key: i.name, name: i.name }, {
default: () => i.children.map((j) => h(Child, { key: j.name, name: j.name, host: i }))
})
}))
}
}).mount('#app')
What is expected?
What is actually happening?
System Info
No response
Any additional comments?
No response
when vode "child-2" was unmounted due to the unmounting of vnode "parent", it's corresponding element didn't removed. Shouldn't a vnode preserve a reference to its corresponding element?
but why this example act as excepted: https://stackblitz.com/edit/vitejs-vite-pdzx73?file=src%2Fmain.js
when vode "child-2" was unmounted due to the unmounting of vnode "parent", it's corresponding element didn't removed. Shouldn't a vnode preserve a reference to its corresponding element?
When Vue unmounts parent
, there is no need to do anything with child-2
as that is a child of parent
, as far as Vue knows from the vdom. So child-2
would be removed alongside its parent
anyway.
Generally: Manually moving around elements that Vue controls will usually mess up your rendering. Avoid doing that.