vue3 - Use of the built-in component Teleport

insert image description here

<Teleport>is a built-in component that can "transfer" a part of a template inside a component to a location outside the component's DOM structure.

1. Usage scenario:

Part of a component template is logically subordinate to the component, but from the perspective of the entire application view, it should be rendered elsewhere in the DOM outside the entire Vue application;

That is to say, I have a full-screen pop-up box (modal box) or Toast light prompt component, which may be used in multiple components, but because the node is nested too deeply, I want to put its dom element at the end On the outer container; control its display and hiding through component parameter passing;

这样做的好处是: Handling the positioning, z-index and style of nested components will become simple; it will not cause style pollution;
and it will be much more convenient and easier to manage;

2. Use with components

<Teleport>Only the rendered DOM structure is changed, it will not affect the logical relationship between components. That is to say, if <Teleport>contains a component, then the component always <teleport>maintains a logical parent-child relationship with the component that uses . Incoming props and fired events will work as usual.

This also means that injections from parent components will also work as expected, and child components will be nested under the parent component in Vue Devtools instead of where the actual content moves.

The renderings are as follows:

Click the button to pop up the modal box, click OK to close the modal box, and the position of the rendered node is under the body (or any node);

insert image description hereThe implementation is as follows

parent component:

<script setup>
import {
    
     reactive, ref, watch, onMounted } from "vue";
// 引入模态框组件
import Modal from "../../components/component/Modal.vue";
let isShow = ref(false);

// 显示模态框
const showModel = () => {
    
    
  isShow.value = true;
};
</script>

<template>
 <div class="container">
    <!-- 预留Teleport组件的位置 可以放到这里 to=".container" -->
  </div>
  <div id="container">
    <!-- 预留Teleport组件的位置 可以放到这里 to="#container -->
  </div>
  
  <div class="teleport">
    <h4>teleport组件演示</h4>
    <button ="showModel">点击弹出模态框</button>
    
   <!-------------------------------------Teleport使用 ------------------------------------>
    <Teleport to="body">
      <!-- 使用这个 modal 组件,传入 prop -->
      <modal :show="isShow" ="isShow = false">
        <template #header>
          <h3>custom header</h3>
        </template>
      </modal>
    </Teleport>
    
  </div>
</template>

<style scoped></style>

Subcomponent Modal.vue:

<script setup>
const props = defineProps({
    
    
  show: Boolean,
});
</script>

<template>
  <Transition name="modal">
    <div v-if="show" class="modal-mask">
      <div class="modal-container">
        <div class="modal-header">
          <slot name="header">default header</slot>
        </div>

        <div class="modal-body">
          <slot name="body">default body</slot>
        </div>

        <div class="modal-footer">
          <slot name="footer">
            default footer
            <button class="modal-default-button" ="$emit('close')">
              OK
            </button>
          </slot>
        </div>
      </div>
    </div>
  </Transition>
</template>

<style>
.modal-mask {
    
    
  position: fixed;
  z-index: 9998;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  transition: opacity 0.3s ease;
}

.modal-container {
    
    
  width: 300px;
  margin: auto;
  padding: 20px 30px;
  background-color: #fff;
  border-radius: 2px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
  transition: all 0.3s ease;
}

.modal-header h3 {
    
    
  margin-top: 0;
  color: #42b983;
}

.modal-body {
    
    
  margin: 20px 0;
}

.modal-default-button {
    
    
  float: right;
}

/*
 * 对于 transition="modal" 的元素来说
 * 当通过 Vue.js 切换它们的可见性时
 * 以下样式会被自动应用。
 *
 * 你可以简单地通过编辑这些样式
 * 来体验该模态框的过渡效果。
 */

.modal-enter-from {
    
    
  opacity: 0;
}

.modal-leave-to {
    
    
  opacity: 0;
}

.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
    
    
  -webkit-transform: scale(1.1);
  transform: scale(1.1);
}
</style>

3, the use of to attribute

<Teleport>Receives a to prop specifying the destination of the transfer. The value of to can be a CSS selector string (such as: to=".container", to="#container), or a DOM element object (such as: to="body").

What this code does is tell Vue 把以下模板片段传送到 你所期望的标签下面.

4. Disable Teleport

In some scenarios, it may need to be disabled according to the situation <Teleport>, and it needs to be added disabledas false;

   <Teleport to="body" disabled="false">
      <!-- 使用这个 modal 组件,传入 prop -->
      <modal :show="isShow" ="isShow = false">
        <template #header>
          <h3>custom header</h3>
        </template>
      </modal>
    </Teleport>

Then this component is equivalent to an ordinary pop-up window component at this time, and will no longer be moved;

5. Multiple Teleport shared targets

A reusable modal component may have multiple instances at the same time. For this type of scenario, multiple <Teleport>components can mount their content on the same target element, 而顺序就是简单的顺次追加and the ones mounted later will be placed at a later position under the target element.

For example, the following use case:

<Teleport to="#modals">
  <div>A</div>
</Teleport>
<Teleport to="#modals">
  <div>B</div>
</Teleport>

The rendered result is:

html
<div id="modals">
  <div>A</div>
  <div>B</div>
</div>

Guess you like

Origin blog.csdn.net/qq_43886365/article/details/131190061