首頁 >web前端 >Vue.js >深入詳解Vue中使用Teleport組件的方法

深入詳解Vue中使用Teleport組件的方法

青灯夜游
青灯夜游轉載
2023-04-04 19:28:331259瀏覽

Vuejs中如何使用Teleport元件?以下這篇文章就來帶大家了解Vue中使用Teleport元件的方法,希望對大家有幫助!

深入詳解Vue中使用Teleport組件的方法

DOM結構相對比較複雜,層級嵌套比較深的元件內,需要根據相對應的模組業務處理一些邏輯,該邏輯屬於當前元件

但是從整個頁面應用的視圖上看,它在DOM中應該被渲染在整個vue應用外部的其他地方,不能影響元件的結構

比較常見的應用場景:就是全螢幕的模態框,控制元素的位置,也是可以處理的,但是比較麻煩

#在理想情況下,我們希望在具體的元件中,給元素綁定的事件,與具體要控制的DOM元素結構在同一個元件中,具體的位置處,保持一定的相關聯性。 【相關推薦:vuejs影片教學web前端開發

#而不用特意的把一些DOM結構給分離出去,然而,在同一元件中,觸發模態框的按鈕和模態框本身在同一元件中

因為他們都與元件的開關狀態有相關聯,模態框與按鈕一起渲染在應用 DOM結構很深的地方,會導致模態框的css佈局位置非常難控制

鑑於這樣的場景和困難,Vue官方提供了一個Teleport 元件,很好的可以解決這個問題,讓開發者不需要顧慮DOM結構的問題

01-元件套組層次結構很深時

例如:現在有兩個元件,父元件,子元件,在後代元件內,新增一個按鈕,彈出一個模態方塊,讓它在頁面垂直水平居中顯示

如下所示,父元件如下所示App.vue

<template>
    <div class="App">
        我是父组件
        <Child />
    </div>
</template>
<script setup>
    import Child from "./Child.vue"
</script>
<style>
.App {
    width: 400px;
    height: 400px;
    background:red;
}
</style>

如下是Child元件,範例程式碼如下圖Child.vue,我們需要在孫(後代)元件,新增一個按鈕,點擊按鈕,彈出一個彈框,水平垂直居中顯示在頁面中央

<template>
    <div class="child">
      <p>我是子组件</p>
        <button @click="isModel=true">打开模态框</button>
        <div class="mask-dialog" v-if="isModel">
             <div class="box">
                  <h2>我是标题</h2>
                  <div>我是弹框内容</div>
                  <div>
                      <button @click="isModel=false">关闭</button>
                  </div>
             </div>
        </div>
    </div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
    width: 300px;
    height:300px;
    background:green;
}
/**灰色遮罩层 */
  .mask-dialog {
    width: 100%;
    height:100%;
    position:absolute;
    left:0;
    top:0;
    background:rgba(0,0,0,0.5)
  }
  
  .box {
    width: 200px;
    height:200px;
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%,-50%);
    background:pink;
    text-align:center;
  }
</style>

上面的子元件中有一個button按鈕來觸發開啟目前元件的模態框,裡面存在著控制彈框的顯示和隱藏的邏輯,當嵌套的組件比較深,複雜時

如果父級元素存在定位,那在控制子元素的位置時,用csstransformposition:absolute,參考物件的變更,會破壞佈局結構,會出現一些css樣式

控制的問題,解決起來會非常的痛苦

那這個Teleport元件就是為了解決這類問題,可以將指定的DOM結構片段,獨立於到元件外面去,不受目前元件佈局結構的影響

經過Teleport的修改後

<template>
    <div class="child">
      <p>我是子组件</p>
        <button @click="isModel=true">打开模态框</button>
        <Teleport to="body">
            <div class="mask-dialog" v-if="isModel">
                 <div class="box">
                      <h2>我是标题1</h2>
                      <div>我是弹框内容</div>
                      <div>
                          <button @click="isModel=false">关闭</button>
                      </div>
                 </div>
            </div>
        </Teleport>  
    </div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
    width: 300px;
    height:300px;
    background:green;
}
/**灰色遮罩层 */
  .mask-dialog {
    width: 100%;
    height:100%;
    position:absolute;
    left:0;
    top:0;
    background:rgba(0,0,0,0.5)
  }
  
  .box {
    width: 200px;
    height:200px;
    position:absolute;
    left:50%;
    top:50%;
    transform:translate(-50%,-50%);
    background:pink;
    text-align:center;
  }
</style>

095a8c77e9bc5f13289f43baf6c8bdc1接收一個 to prop 來指定傳送的目標。 to 的值可以是一個 CSS 選擇器字串,或id,也可以是一個 DOM 元素物件。這段程式碼的功能就是告訴 Vue把以下模板片段傳送到 body 標籤下

<Teleport to="#some-id">html结构代码</Teleport>
<Teleport to=".some-class">html结构代码</Teleport>
<Teleport to="body">html结构代码</Teleport>
<Teleport to="html">html结构代码</Teleport>

02-Teleport元件

#它是Vue官方提供的一個內建元件,它可以將一個元件內部的一部分模板「傳送」到該元件的 DOM 結構外層的位置去 也就是一種能夠將我們的元件html結構移到指定位置的技術

<teleport to="移动到指定的位置,可以是html,body,或id,class">
   里面是Html结构模板内容
</teleport>

#注意

095a8c77e9bc5f13289f43baf6c8bdc1 掛載時,傳送的 to 目標必須已經存在於DOM。理想情況下,這應該是整個 Vue 應用 DOM 樹外部的元素。如果目標元素也是由 Vue 渲染的,你需要確保在掛載 095a8c77e9bc5f13289f43baf6c8bdc1 之前先掛載該元素

這個teleport將指定的模板html,放置到頁面當中指定的位置處,它是有條件的,不是可以任意傳送的

在安裝元件之前,目標元素必須存在,即,目標不能由元件本身呈現,理想情況下應該位於整個Vue元件樹之外。

如下程式碼是不行的

<template>
    <div>
        <Teleport to=".content">
            <div>我是头部的内容</div>
        </Teleport>
         
    </div>
    <div>
        底部内容
        <div></div>
    </div>
</template>
<script setup>
</script>
<style>
h1 {
    color: red;
}
</style>

03-需要知道的

#teleport只是改變了渲染的 DOM 結構,它不會影響組件間的邏輯關係。也就是說,如果 095a8c77e9bc5f13289f43baf6c8bdc1 包含了一個元件,那麼這個元件總是與這個使用了 6c123bcf29012c05eda065ba23259dcb 的元件保持邏輯上的父子關係。傳入的 props 和觸發的事件也會照常運作。

这也意味着来自父组件的注入也会按预期工作,子组件将在 Vue Devtools 中嵌套在父级组件下面,而不是放在实际内容移动到的地方

位置移动了,提现在结构模板上,但是数据逻辑依旧存在关联的

04-如何禁用 Teleport

在某些场景下可能需要视情况禁用 095a8c77e9bc5f13289f43baf6c8bdc1。举例来说,我们想要在桌面端将一个组件当做浮层来渲染,但在移动端则当作行内组件。我们可以通过对 095a8c77e9bc5f13289f43baf6c8bdc1 动态地传入一个 disabled prop 来处理这两种不同情况

<Teleport :disabled="isMobile">
  ...
</Teleport>

这里的 isMobile 状态可以根据 CSS media query 的不同结果动态地更新

05-多个 Teleport 共享目标时

一个可重用的模态框组件可能同时存在多个实例。对于此类场景,多个 095a8c77e9bc5f13289f43baf6c8bdc1 组件可以将其内容挂载在同一个目标元素上,而顺序就是简单的顺次追加,后挂载的将排在目标元素下更后面的位置上

比如下面这样的用例

<Teleport to=".content">
  <div>A</div>
</Teleport>
<Teleport to=".content">
  <div>B</div>
</Teleport>

渲染的结果为

<div class="content">
  <div>A</div>
  <div>B</div>
</div>

总结

这个teleport组件在实际开发中还是很实用的,能够解决当组件嵌套层级很深,而后代组件中的模板,想要脱离当前组件结构,解决css布局层面的干扰,那就可以用这个teleport组件

(学习视频分享:vuejs入门教程编程基础视频

以上是深入詳解Vue中使用Teleport組件的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.cn。如有侵權,請聯絡admin@php.cn刪除