Vue 3 有一个新的 Teleport 功能,它取代了 vue 2 中的 portal-vue 插件。但是,我发现不可能将组件移植到 vue 控制的地方(=在 vue 应用程序中)。它仅在移植到外部(主体、其他元素......)时有效。
const app = {
template: `
<div>
<h1>App</h1>
<div id="dest"></div>
<comp />
</div>`
}
Vue.createApp(app).component('comp', {
template: `
<div>
A component
<Teleport to="#dest">
Hello From Portal
</Teleport>
</div>`
}).mount('#app')Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/vue@3.0.0-rc.9/dist/vue.global.js"></script>
<div id="app"></div>Run Code Online (Sandbox Code Playgroud)
如您所见,控制台甚至报告说需要已经渲染传送目标。但是我怎么能告诉 vue 先渲染哪个组件呢?在我的例子中,目标在传送前的 dom 中。
这在 portal-vue 中不是问题,而且非常令人失望,因为它使整个概念变得不那么可用。
我有一个使用 teleport to 的组件,测试 html 似乎没有按预期工作。我找不到有关此特定用途的任何文档。这是我的测试:
describe('MetaHead', () => {
it('dynamic metadata tags contain custom text', () => {
let title = 'My Page';
let description = 'Some description about my page';
// This component uses Vue3's teleport to tag <head>
// we must modify wrapper to contain such tag
document.body.innerHTML = `
<head>
<div id="app"></div>
</head>
`
const wrapper = mount(MetaHead, {
attachTo: document.getElementById('app'),
props: {
title,
description
},
global:{
mocks: {
$route:{fullPath: 'full/path'}
}
}
})
expect(wrapper.html()).toContain(title)
expect(wrapper.html()).toContain(description) …Run Code Online (Sandbox Code Playgroud) 在 Vue 3 中,可以像这样将组件传送到body标签:
<template>
<button @click="modalOpen = true">
Open full screen modal! (With teleport!)
</button>
<teleport to="body">
<div v-if="modalOpen" class="modal">
<div>
I'm a teleported modal!
(My parent is "body")
<button @click="modalOpen = false">
Close
</button>
</div>
</div>
</teleport>
</template>
<script>
export default {
data() {
return {
modalOpen: false
}
}
};
</script>
Run Code Online (Sandbox Code Playgroud)
这会导致上面的模态对话在body标签中呈现。如何在 Vue 2 中实现类似的功能?