記錄-VueJs中如何使用Teleport組件

来源:https://www.cnblogs.com/smileZAZ/archive/2023/04/07/17296909.html
-Advertisement-
Play Games

這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 在DOM結構相對比較複雜,層級嵌套比較深的組件內,需要根據相對應的模塊業務處理一些邏輯,該邏輯屬於當前組件 但是從整個頁面應用的視圖上看,它在DOM中應該被渲染在整個vue應用外部的其他地方,不能影響組件的結構 比較常見的應用場景:就是全 ...


這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助

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

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

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

在理想情況下,我們希望在具體的組件中,給元素綁定的事件,與具體要控制的DOM元素結構在同一個組件中,具體的位置處,保持一定的相關聯性

而不用特意的把一些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按鈕來觸發打開當前組件的模態框,裡面存在著控制彈框的顯示和隱藏的邏輯,當嵌套的組件比較深,複雜時

如果父級元素存在定位,那在控制子元素的位置時,用csstransform或者position: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>

<Teleport>接收一個 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>

註意

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

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

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

如下代碼是不行的

<template>
    <div class="header">
        <Teleport to=".content">
            <div>我是頭部的內容</div>
        </Teleport>
         
    </div>
    <div class="footer">
        底部內容
        <div class="content"></div>
    </div>
</template>
<script setup>
</script>
<style lang="less">
h1 {
    color: red;
}
</style> 

03-需要知道的

teleport只是改變了渲染的 DOM 結構,它不會影響組件間的邏輯關係。也就是說,如果 <Teleport> 包含了一個組件,那麼該組件始終和這個使用了 <teleport> 的組件保持邏輯上的父子關係。傳入的 props 和觸發的事件也會照常工作。

這也意味著來自父組件的註入也會按預期工作,子組件將在 Vue Devtools 中嵌套在父級組件下麵,而不是放在實際內容移動到的地方

位置移動了,提現在結構模板上,但是數據邏輯依舊存在關聯的

04-如何禁用 Teleport

在某些場景下可能需要視情況禁用 <Teleport>。舉例來說,我們想要在桌面端將一個組件當做浮層來渲染,但在移動端則當作行內組件。我們可以通過對 <Teleport> 動態地傳入一個 disabled prop 來處理這兩種不同情況

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

05-多個 Teleport 共用目標時

一個可重用的模態框組件可能同時存在多個實例。對於此類場景,多個 <Teleport> 組件可以將其內容掛載在同一個目標元素上,而順序就是簡單的順次追加,後掛載的將排在目標元素下更後面的位置上

比如下麵這樣的用例

<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組件

本文轉載於:

https://juejin.cn/post/7217731723509547069

如果對您有所幫助,歡迎您點個關註,我會定時更新技術文檔,大家一起討論學習,一起進步。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Hadoop簡介安裝 狹義上Hadoop指的是Apache軟體基金會的一款開源軟體用java語言實現,開源允許用戶使用簡單的編程模型實現跨機器集群對海量數據進行分散式計算處理 Hadoop核心組件 Hadoop HDFS(分散式文件存儲系統):解決海量數據存儲 Hadoop YARN(集群資源管理和 ...
  • 摘要:本文主要通過實例講解如何通過gs_cpuwatcher.sh 腳本尋找CPU占用高語句。 本文分享自華為雲社區《GaussDB(DWS) gs_cpuwatcher.sh 腳本如何尋找CPU占用高語句》,作者:fighttingman。 【工具名稱】 gs_cpuwatcher 【功能描述】 ...
  • 為什麼要分庫分表 用戶請求量太大 單伺服器TPS、記憶體、IO都是有上限的,需要將請求打散分佈到多個伺服器 。 單庫數據量太大 單個資料庫處理能力有限;單庫所在伺服器的磁碟空間有限;單庫上的操作IO有瓶頸 。 單表數據量太大 查詢、插入、更新操作都會變慢,在加欄位、加索引、機器遷移都會產生高負載,影響 ...
  • Mysql 01 使用CMD連接資料庫 -- 在控制台連接資料庫(需將位置切換到mysql所在地址) mysql -u root -p password:12345 -- 修改mysql賬戶密碼及許可權,安裝配置完後慎用 update mysql.user set authentication_str ...
  • 前言 不同微信版本,關閉廣告的方式不一樣,今天嘗試關閉微信版本 8.0.33 廣告,但是發現最後還是關不掉,故寫下此文,希望對大家死了關閉廣告這條心! 操作如下 步驟一:點擊設置—>關於微信 步驟二:點擊進入《隱私保護指引》 步驟三:在第一大類中找到 1.34 小類,其中有個藍色字樣《個性化廣告》, ...
  • Flutter 是由 Google 創建的免費開源的移動應用程式開發框架。可以用它為 iOS、Android 和 Web 平臺,開發界面華麗、高性能、響應式的應用程式。Flutter 基於 Dart 編程語言,並使用 Skia 圖形庫來渲染其組件。 和很多其它框架一樣,Flutter 宣稱其主要特性 ...
  • 最近用 TypeScript 寫 npm 包,各種模塊、命名空間、全局定義等等擾得我睡不著覺。我苦心研究,總結了幾個比較冷門的,國內貌似基本上找不到資料的導入導出用法,順便在其中又插入一些不那麼冷門的用法,於是本篇文章來了。 ...
  • 1.ref 和 $refs ref 被用來給元素或子組件註冊引用信息, 引用信息將會註冊在父組件的 $refs 對象上,如果是在普通的DOM元素上使用,引用指向的就是DOM元素,如果是在子組件上,引用就指向組件的實例。 $refs 是一個對象,持有已註冊過 ref 的所有的子組件。 ref用法: r ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...