溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue3中內置組件Teleport怎么使用

發(fā)布時間:2023-04-27 11:17:22 來源:億速云 閱讀:145 作者:iii 欄目:開發(fā)技術

本篇內容介紹了“Vue3中內置組件Teleport怎么使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

    1. 基本概念

    1.1 簡單理解

    不管是 Vue2 還是 Vue3 中都有內置組件的存在,如 component 內置組件、transition 內置組件等等。內置組件就是官方給我們封裝的全局組件,我們直接拿來用就可以了。

    在 Vue3 中新增了 Teleport 內置組件,先來看下官方文檔是怎么解釋的。

    <Teleport> 是一個內置組件,它可以將一個組件內部的一部分模板“傳送”到該組件的 DOM 結構外層的位置去。

    通俗解釋:

    teleport 是一個內置組件,我們都知道 HTML 是由層級關系的,Vue3 中的組件也是有層級關系的。

    假如在父組件中引用了一個子組件,那么渲染成頁面后這個子組件 HTML 也是必然被父組件 HTML 包含的。

    但是如果把子組件放置到了 teleport 組件中,那么我們就可以指定該子組件渲染到父組件之外的其它 DOM 節(jié)點下,比如 body 或者其它的 DOM 等等。這就有點類似與“傳送”了。

    1.2 典型案例

    我們使用 Vue 的 UI 組件庫的時候,經常會用到模態(tài)框這個組件。如:使用 Element-plus 的模態(tài)框。

    <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 屬性。

    Vue3中內置組件Teleport怎么使用

    可以看到雖然彈窗組件是寫在 App.vue 組件里面的,但是渲染出來的結果卻是彈窗組件屬于 body 節(jié)點,這是因為利用了 Element-plus 中彈窗的 append-to-body 屬性,我們把該屬性去掉再看看什么結果:

    Vue3中內置組件Teleport怎么使用

    可以看到彈窗組件又乖乖的跑到了 App.vue 組件下面。

    為何要這樣做?

    很簡單,假如有非常多的彈窗,那么如何管理它們的 z-index 呢,也就是同時彈窗時的層級關系,如果每個彈窗都在各自的父組件中,那么我們是沒法控制的,所有有必要把它們都擰出來,放在同一個父元素下面,這樣就可以方便的設置層級關系了。

    這和 teleport 組件有什么關系嗎?有很大的關系,上面彈窗的 append-to-body 屬性效果是 Element 給我們做的,要是我們想自己實現這樣的效果,該怎么辦呢?我們就可以使用內置組件 teleport 了。

    2. 基礎使用

    2.1 傳送 DOM 節(jié)點

    <template>
      <div class="app">
        App組件
        <Teleport to="body">
          <div>我是被 teleport 包裹的元素</div>
        </Teleport>
      </div>
    </template>

    Vue3中內置組件Teleport怎么使用

    從上圖可以看出,Teleport 包裹的元素雖然是屬于 app.vue 組件,但是渲染過后它卻被渲染在了 body 這個 dom 元素下面了。
    這都得歸功于 Teleport 得傳送功能,它的用法很簡單,語法代碼如下:

    其中 to 就是“傳送”的目的地了,即需要把包裹的內容傳送到何處去。

    <Teleport to="body">
    </Teleport>
    
    to 允許接收值:
    期望接收一個 CSS 選擇器字符串或者一個真實的 DOM 節(jié)點。
    提示:
    <Teleport> 掛載時,傳送的 to 目標必須已經存在于 DOM 中。理想情況下,這應該是整個 Vue 應用 DOM 樹外部的一個元素。
    如果目標元素也是由 Vue 渲染的,你需要確保在掛載 <Teleport> 之前先掛載該元素。

    2.2 傳送組件

    < Teleport > 只改變了渲染的 DOM 結構,它不會影響組件間的邏輯關系。

    也就是說,如果 < Teleport > 包含了一個組件,那么該組件始終和這個使用了 < teleport > 的組件保持邏輯上的父子關系。傳入的 props 和觸發(fā)的事件也會照常工作。

    這也意味著來自父組件的注入也會按預期工作,子組件將在 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>

    Vue3中內置組件Teleport怎么使用

    2.3 禁用傳送功能

    在某些場景下可能需要視情況禁用 < Teleport >,我們可以通過對 < Teleport > 動態(tài)地傳入一個 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>

    Vue3中內置組件Teleport怎么使用

    2.4 多個元素傳送給一個節(jié)點

    多個 < 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怎么使用

    “Vue3中內置組件Teleport怎么使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

    向AI問一下細節(jié)

    免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI