对于teleport
组件,咱们先来看一下官网是怎么说的吧。
Teleport
提供了一种洁净的办法,容许咱们管制在DOM
中哪个父节点下渲染了HTML
,而不用求助于全局状态或将其拆分为两个组件。
简略的来说就是teleport
能够管制在哪一个dom
下来渲染你的组件,去解决一些应用组件时受到父元素款式影响的问题。
间接来看一个例子吧。咱们写一个modal弹窗的组件。点击按钮使其呈现,再次点击使其敞开。
Modal.vue
<template> <div id="modal"> <h2>这是一个modal</h2> </div></template><script lang="ts">export default {};</script><style>#modal { width: 200px; height: 200px; border: 2px solid black; background: white; position: fixed; left: 50%; top: 50%; margin-left: -100px; margin-top: -100px;}</style>
TeleportCom.vue
<template> <div class="teleport-com"> <button @click="showModal">{{ show ? "暗藏" : "显示" }}</button> <Modal v-if="show" /> </div></template><script lang="ts">import { defineComponent, reactive, toRefs } from "vue";import Modal from "@/components/Modal.vue";export default defineComponent({ name: "teleport-com", components: { Modal, }, setup() { const data = reactive({ show: false, showModal: () => { data.show = !data.show; }, }); const refData = toRefs(data); return { ...refData, }; },});</script><style lang="scss" scoped>.teleport-com {}</style>
来看一下成果
会发现没有在Modal.vue
组件写文字居中,然而文字居中了。这是因为Modal
组件渲染在了app
节点中,受到了app
节点款式的影响。
咱们怎么在不批改Modal
组件上的前提上解决这个问题了,teleport
提供了解决方案。
- 批改
index.html
,新增一个id为modal-container
的div
<!DOCTYPE html><html lang=""> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width,initial-scale=1.0" /> <link rel="icon" href="<%= BASE_URL %>favicon.ico" /> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong >We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong > </noscript> <div id="app"></div> // 新增一个id为modal-container的div <div id="modal-container"></div> <!-- built files will be auto injected --> </body></html>
批改
Modal.vue
组件,应用teleport
组件包裹
<template>
// 应用teleport组件包裹
<teleport to="#modal-container">
<div id="modal">
<h2>这是一个modal</h2>
</div>
</teleport>
</template>
<script lang="ts">
export default {};
</script>
<style>modal {
width: 200px;
height: 200px;
border: 2px solid black;
background: white;
position: fixed;
left: 50%;
top: 50%;
margin-left: -100px;
margin-top: -100px;
}
</style>
查看成果,款式不受到app节点管制,且不在渲染在app节点中
- 或者咱们还能这样改,重用性更强。把Modal.vue还原为文章最后的样子,批改
TeleportCom.vue
,应用teleport
间接包裹应用的组件
<template> <div class="teleport-com"> <button @click="showModal">{{ show ? "暗藏" : "显示" }}</button> // 应用`teleport`间接包裹应用的组件 <teleport to="#modal-container"> <Modal v-if="show" /> </teleport> </div></template><script lang="ts">import { defineComponent, reactive, toRefs } from "vue";import Modal from "@/components/Modal.vue";export default defineComponent({ name: "teleport-com", components: { Modal, }, setup() { const data = reactive({ show: false, showModal: () => { data.show = !data.show; }, }); const refData = toRefs(data); return { ...refData, }; },});</script><style lang="scss" scoped>.teleport-com {}</style>
能够看到也是一样的成果哟