mirror of https://github.com/vuejs/core.git
fix(teleport): handle deferred teleport updates before and after mount (#13350)
close #13349
This commit is contained in:
parent
163b3651d1
commit
d15dce3142
|
@ -16,6 +16,7 @@ import {
|
||||||
render,
|
render,
|
||||||
serialize,
|
serialize,
|
||||||
serializeInner,
|
serializeInner,
|
||||||
|
useModel,
|
||||||
withDirectives,
|
withDirectives,
|
||||||
} from '@vue/runtime-test'
|
} from '@vue/runtime-test'
|
||||||
import {
|
import {
|
||||||
|
@ -144,6 +145,62 @@ describe('renderer: teleport', () => {
|
||||||
`"<!--teleport start--><!--teleport end--><div>Footer</div><div id="targetId"><div>bar</div></div>"`,
|
`"<!--teleport start--><!--teleport end--><div>Footer</div><div id="targetId"><div>bar</div></div>"`,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// #13349
|
||||||
|
test('handle deferred teleport updates before and after mount', async () => {
|
||||||
|
const root = document.createElement('div')
|
||||||
|
document.body.appendChild(root)
|
||||||
|
|
||||||
|
const show = ref(false)
|
||||||
|
const data2 = ref('2')
|
||||||
|
const data3 = ref('3')
|
||||||
|
|
||||||
|
const Comp = {
|
||||||
|
props: {
|
||||||
|
modelValue: {},
|
||||||
|
modelModifiers: {},
|
||||||
|
},
|
||||||
|
emits: ['update:modelValue'],
|
||||||
|
setup(props: any) {
|
||||||
|
const data2 = useModel(props, 'modelValue')
|
||||||
|
data2.value = '2+'
|
||||||
|
return () => h('span')
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
createDOMApp({
|
||||||
|
setup() {
|
||||||
|
setTimeout(() => (show.value = true), 5)
|
||||||
|
setTimeout(() => (data3.value = '3+'), 10)
|
||||||
|
},
|
||||||
|
render() {
|
||||||
|
return h(Fragment, null, [
|
||||||
|
h('span', { id: 'targetId001' }),
|
||||||
|
show.value
|
||||||
|
? h(Fragment, null, [
|
||||||
|
h(Teleport, { to: '#targetId001', defer: true }, [
|
||||||
|
createTextVNode(String(data3.value)),
|
||||||
|
]),
|
||||||
|
h(Comp, {
|
||||||
|
modelValue: data2.value,
|
||||||
|
'onUpdate:modelValue': (event: any) =>
|
||||||
|
(data2.value = event),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
: createCommentVNode('v-if'),
|
||||||
|
])
|
||||||
|
},
|
||||||
|
}).mount(root)
|
||||||
|
|
||||||
|
expect(root.innerHTML).toMatchInlineSnapshot(
|
||||||
|
`"<span id="targetId001"></span><!--v-if-->"`,
|
||||||
|
)
|
||||||
|
|
||||||
|
await new Promise(r => setTimeout(r, 10))
|
||||||
|
expect(root.innerHTML).toMatchInlineSnapshot(
|
||||||
|
`"<span id="targetId001">3+</span><!--teleport start--><!--teleport end--><span></span>"`,
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function runSharedTests(deferMode: boolean) {
|
function runSharedTests(deferMode: boolean) {
|
||||||
|
|
|
@ -164,15 +164,16 @@ export const TeleportImpl = {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTeleportDeferred(n2.props)) {
|
if (isTeleportDeferred(n2.props)) {
|
||||||
|
n2.el!.__isMounted = false
|
||||||
queuePostRenderEffect(() => {
|
queuePostRenderEffect(() => {
|
||||||
mountToTarget()
|
mountToTarget()
|
||||||
n2.el!.__isMounted = true
|
delete n2.el!.__isMounted
|
||||||
}, parentSuspense)
|
}, parentSuspense)
|
||||||
} else {
|
} else {
|
||||||
mountToTarget()
|
mountToTarget()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (isTeleportDeferred(n2.props) && !n1.el!.__isMounted) {
|
if (isTeleportDeferred(n2.props) && n1.el!.__isMounted === false) {
|
||||||
queuePostRenderEffect(() => {
|
queuePostRenderEffect(() => {
|
||||||
TeleportImpl.process(
|
TeleportImpl.process(
|
||||||
n1,
|
n1,
|
||||||
|
@ -186,7 +187,6 @@ export const TeleportImpl = {
|
||||||
optimized,
|
optimized,
|
||||||
internals,
|
internals,
|
||||||
)
|
)
|
||||||
delete n1.el!.__isMounted
|
|
||||||
}, parentSuspense)
|
}, parentSuspense)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue