首頁 > web前端 > Vue.js > Vue3中內建元件Teleport怎麼使用

Vue3中內建元件Teleport怎麼使用

PHPz
發布: 2023-05-12 10:07:05
轉載
2289 人瀏覽過

    1. 基本概念

    1.1 簡單理解

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

    在 Vue3 中新增了 Teleport 內建元件,先來看下官方文件是怎麼解釋的。

    是內建元件,它可以將一個元件內部的一部分模板「傳送」到該元件的 DOM 結構外層的位置去。

    通俗解釋:

    teleport 是內建元件,我們都知道 HTML 是由層級關係的,Vue3 中的元件也是有層級關係的。

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

    但是如果把子元件放置到了 teleport 元件中,那麼我們就可以指定該子元件渲染到父元件之外的其它 DOM 節點下,例如 body 或其它的 DOM 等等。這就有點類似與「傳送」了。

    1.2 典型案例

    我們使用 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 &#39;vue&#39;;
    export default {
      setup(){
        const dialogVisible = ref(false);
        return {
          dialogVisible
        }
      } 
    }
    </script>
    登入後複製

    上段程式碼中在 App.vue 元件裡面引用了 Element-plus 的彈窗元件,並且新增了一個 append-to-body 屬性。

    Vue3中內建元件Teleport怎麼使用

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

    Vue3中內建元件Teleport怎麼使用

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

    為何要這麼做?

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

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

    2. 基礎使用

    2.1 傳送DOM 節點

    <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 节点。
    提示:
    <Teleport> 挂载时,传送的 to 目标必须已经存在于 DOM 中。理想情况下,这应该是整个 Vue 应用 DOM 树外部的一个元素。
    如果目标元素也是由 Vue 渲染的,你需要确保在挂载 <Teleport> 之前先挂载该元素。
    登入後複製

    2.2 傳送元件

    < 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 &#39;vue&#39;;
    import ChildComponent from &#39;@/components/childComponent&#39;;
    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 &#39;vue&#39;;
    export default {
      props:{
        modelValue:{
          default:0,
        }
      },
      setup(props,{emit}) {
        const inputVal = ref(null);
        const userInput = () => {
          emit(&#39;update:modelValue&#39;, inputVal.value)
        };
    
        watch(props,(newVal,oldVal) => {
          inputVal.value = props.modelValue;
        },{immediate:true})
        return {
          userInput,
          inputVal,
        }
      },
    }
    </script>
    登入後複製

    Vue3中內建元件Teleport怎麼使用

    2.3 停用傳送功能

    在某些場景下可能需要視情況停用< 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 &#39;vue&#39;;
    export default {
      setup(){
        const message = ref(&#39;我是在 App 组件内部&#39;);
        return {
          message,
        }
      } 
    }
    </script>
    登入後複製

    Vue3中內建元件Teleport怎麼使用

    2.4 多個元素傳送給一個節點

    多個< 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怎麼使用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    相關標籤:
    來源:yisu.com
    本網站聲明
    本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
    熱門教學
    更多>
    最新下載
    更多>
    網站特效
    網站源碼
    網站素材
    前端模板