您好,登錄后才能下訂單哦!
本篇內容介紹了“Vue3中內置組件Teleport怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
不管是 Vue2 還是 Vue3 中都有內置組件的存在,如 component 內置組件、transition 內置組件等等。內置組件就是官方給我們封裝的全局組件,我們直接拿來用就可以了。
在 Vue3 中新增了 Teleport 內置組件,先來看下官方文檔是怎么解釋的。
<Teleport> 是一個內置組件,它可以將一個組件內部的一部分模板“傳送”到該組件的 DOM 結構外層的位置去。
通俗解釋:
teleport 是一個內置組件,我們都知道 HTML 是由層級關系的,Vue3 中的組件也是有層級關系的。
假如在父組件中引用了一個子組件,那么渲染成頁面后這個子組件 HTML 也是必然被父組件 HTML 包含的。
但是如果把子組件放置到了 teleport 組件中,那么我們就可以指定該子組件渲染到父組件之外的其它 DOM 節點下,比如 body 或者其它的 DOM 等等。這就有點類似與“傳送”了。
我們使用 Vue 的 UI 組件庫的時候,經常會用到模態框這個組件。如:使用 Element-plus 的模態框。
<template> <el-button @click="dialogVisible = true">打開彈窗</el-button> <el-dialog v-model="dialogVisible" append-to-body title="我是彈窗" width="30%"> </el-dialog> </template> <script> import { ref } from 'vue'; export default { setup(){ const dialogVisible = ref(false); return { dialogVisible } } } </script>
上段代碼中在 App.vue 組件里面引用了 Element-plus 的彈窗組件,并且添加了一個 append-to-body 屬性。
可以看到雖然彈窗組件是寫在 App.vue 組件里面的,但是渲染出來的結果卻是彈窗組件屬于 body 節點,這是因為利用了 Element-plus 中彈窗的 append-to-body 屬性,我們把該屬性去掉再看看什么結果:
可以看到彈窗組件又乖乖的跑到了 App.vue 組件下面。
為何要這樣做?
很簡單,假如有非常多的彈窗,那么如何管理它們的 z-index 呢,也就是同時彈窗時的層級關系,如果每個彈窗都在各自的父組件中,那么我們是沒法控制的,所有有必要把它們都擰出來,放在同一個父元素下面,這樣就可以方便的設置層級關系了。
這和 teleport 組件有什么關系嗎?有很大的關系,上面彈窗的 append-to-body 屬性效果是 Element 給我們做的,要是我們想自己實現這樣的效果,該怎么辦呢?我們就可以使用內置組件 teleport 了。
<template> <div class="app"> App組件 <Teleport to="body"> <div>我是被 teleport 包裹的元素</div> </Teleport> </div> </template>
從上圖可以看出,Teleport 包裹的元素雖然是屬于 app.vue 組件,但是渲染過后它卻被渲染在了 body 這個 dom 元素下面了。
這都得歸功于 Teleport 得傳送功能,它的用法很簡單,語法代碼如下:
其中 to 就是“傳送”的目的地了,即需要把包裹的內容傳送到何處去。
<Teleport to="body"> </Teleport> to 允許接收值: 期望接收一個 CSS 選擇器字符串或者一個真實的 DOM 節點。 提示: <Teleport> 掛載時,傳送的 to 目標必須已經存在于 DOM 中。理想情況下,這應該是整個 Vue 應用 DOM 樹外部的一個元素。 如果目標元素也是由 Vue 渲染的,你需要確保在掛載 <Teleport> 之前先掛載該元素。
< Teleport > 只改變了渲染的 DOM 結構,它不會影響組件間的邏輯關系。
也就是說,如果 < Teleport > 包含了一個組件,那么該組件始終和這個使用了 < teleport > 的組件保持邏輯上的父子關系。傳入的 props 和觸發的事件也會照常工作。
這也意味著來自父組件的注入也會按預期工作,子組件將在 Vue Devtools 中嵌套在父級組件下面,而不是放在實際內容移動到的地方。
// 父組件 <template> <div class="app"> <Teleport to="body"> <div>被 teleport 包裹的組件-- {{count}}</div> <ChildComponent v-model="count"/> </Teleport> </div> </template> <script> import { ref } from 'vue'; import ChildComponent from '@/components/childComponent'; export default { components:{ ChildComponent }, setup(){ const count = ref(100); return { count, } } } </script>
// 子組件 <template> 子組件:<input type="text" v-model.number="inputVal" @input="userInput"> </template> <script> import { ref, watch } from 'vue'; export default { props:{ modelValue:{ default:0, } }, setup(props,{emit}) { const inputVal = ref(null); const userInput = () => { emit('update:modelValue', inputVal.value) }; watch(props,(newVal,oldVal) => { inputVal.value = props.modelValue; },{immediate:true}) return { userInput, inputVal, } }, } </script>
在某些場景下可能需要視情況禁用 < Teleport >,我們可以通過對 < Teleport > 動態地傳入一個 disabled prop 來處理這兩種不同情況( disabled 屬性接收一個 Boolean 值,true 代表不允許傳送,false 代表傳送)。
<template> <div class="app"> app組件 <Teleport to="body" :disabled="true"> <p>我是被 teleport 包裹的元素</p> <p>{{ message }}</p> </Teleport> </div> </template> <script> import { ref } from 'vue'; export default { setup(){ const message = ref('我是在 App 組件內部'); return { message, } } } </script>
多個 < Teleport > 組件可以將其內容掛載在同一個目標元素上,而順序就是簡單的順次追加,后掛載的將排在目標元素下更后面的位置上。
<!-- index.html --> <body> <div id="app"></div> <div id="customDom"></div> </body>
<template> app組件 <Teleport to="#customDom"> <p>我是被 teleport 包裹的一號元素</p> </Teleport> <Teleport to="#customDom"> <p>我是被 teleport 包裹的二號元素</p> </Teleport> </template>
“Vue3中內置組件Teleport怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。