Vuejs中如何使用Teleport元件?以下這篇文章就來帶大家了解Vue中使用Teleport元件的方法,希望對大家有幫助!
在DOM
結構相對比較複雜,層級嵌套比較深的元件內,需要根據相對應的模組業務處理一些邏輯,該邏輯屬於當前元件
但是從整個頁面應用的視圖上看,它在DOM
中應該被渲染在整個vue
應用外部的其他地方,不能影響元件的結構
比較常見的應用場景:就是全螢幕的模態框,控制元素的位置,也是可以處理的,但是比較麻煩
#在理想情況下,我們希望在具體的元件中,給元素綁定的事件,與具體要控制的DOM
元素結構在同一個元件中,具體的位置處,保持一定的相關聯性。 【相關推薦:vuejs影片教學、web前端開發】
#而不用特意的把一些DOM
結構給分離出去,然而,在同一元件中,觸發模態框的按鈕和模態框本身在同一元件中
因為他們都與元件的開關狀態有相關聯,模態框與按鈕一起渲染在應用 DOM
結構很深的地方,會導致模態框的css佈局位置非常難控制
鑑於這樣的場景和困難,Vue
官方提供了一個Teleport
元件,很好的可以解決這個問題,讓開發者不需要顧慮DOM
結構的問題
例如:現在有兩個元件,父元件,子元件,在後代元件內,新增一個按鈕,彈出一個模態方塊,讓它在頁面垂直水平居中顯示
如下所示,父元件如下所示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
按鈕來觸發開啟目前元件的模態框,裡面存在著控制彈框的顯示和隱藏的邏輯,當嵌套的組件比較深,複雜時
如果父級元素存在定位,那在控制子元素的位置時,用css
的transform
或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>
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>
#它是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>
#teleport
只是改變了渲染的 DOM
結構,它不會影響組件間的邏輯關係。也就是說,如果 095a8c77e9bc5f13289f43baf6c8bdc1
包含了一個元件,那麼這個元件總是與這個使用了 6c123bcf29012c05eda065ba23259dcb
的元件保持邏輯上的父子關係。傳入的 props
和觸發的事件也會照常運作。
这也意味着来自父组件的注入也会按预期工作,子组件将在 Vue Devtools
中嵌套在父级组件下面,而不是放在实际内容移动到的地方
位置移动了,提现在结构模板上,但是数据逻辑依旧存在关联的
在某些场景下可能需要视情况禁用 095a8c77e9bc5f13289f43baf6c8bdc1
。举例来说,我们想要在桌面端将一个组件当做浮层来渲染,但在移动端则当作行内组件。我们可以通过对 095a8c77e9bc5f13289f43baf6c8bdc1
动态地传入一个 disabled prop
来处理这两种不同情况
<Teleport :disabled="isMobile"> ... </Teleport>
这里的 isMobile
状态可以根据 CSS media query
的不同结果动态地更新
一个可重用的模态框组件可能同时存在多个实例。对于此类场景,多个 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
组件
以上是深入詳解Vue中使用Teleport組件的方法的詳細內容。更多資訊請關注PHP中文網其他相關文章!