vue3.0 傳送門teleport

咱們先看一段代碼,功能很簡單,模板裏有一個按鈕,點擊按鈕,展現一個模態窗口。javascript

const app = Vue.createApp({
  data() {
    return {
      show: false,
    };
  },
  methods: {
    handleShowModal() {
      this.show = true;
    },
  },
  template: `
    <div class="box" id="box">
      <button @click="handleShowModal">顯示模態窗口</button>
      <div class="modal" v-if="show">模態窗口</div>
    </div>
  `
}

模態窗口樣式以下:css

.box {
  position: absolute;
  width: 100px;
  height: 100px;
  background-color: cadetblue;
}
.modal {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: rgba(0, 0, 0, 0.5);
}

整個模態窗口呈絕對定位,left、right、top、bottom 所有給0,背景色爲黑色半透明。咱們指望的效果,應該點擊按鈕,模態窗口覆蓋整個頁面。html

如今咱們來運行下,咱們會發現,其實模態窗口只覆蓋了 #box 元素,由於 #box 自己就是絕對定位, 模態窗口元素是他的子節點,因此模態窗口只覆蓋了 #box 元素。vue

若是在沒有學習 teleport 以前,咱們會在根節點定義一個模態窗口,在業務組件裏去作調用。可是這樣的話,組件與模態窗口的邏輯就會產生割裂感。那有沒有什麼方法,可讓我模態窗口就寫在這個組件內,但真正呈如今頁面時,能夠動態插入到 元素上的,實際上是有的,咱們只要簡單的修改下 template模板,就能夠實現這個要求了。java

template: `
    <div class="box">
        <button @click="handleShowModal">顯示模態窗口</button>
        <teleport to="body">
            <div class="modal">模態窗口</div>
        </teleport>        
    </div>
`

咱們用 teleport 元素將 modal 包裹起來,並定義屬性 to="body" ,運行頁面,咱們查看 dom 節點,就會發現 modal 元素已經追加到 body 底部了,效果以下。app

--body
  --#root vue根節點
  --.modal 模態窗口

傳送到其餘位置

若是咱們想將 modal 節點傳送到其餘位置,也能夠這麼作。dom

<teleport to="#app">
    <div class="modal">模態窗口</div>
</teleport>

這段代碼就是將 modal 元素追加到 id=app 的元素內,有一點須要注意,我一直說的是追加元素,假如說,原來 #app 內部已經存在其餘節點,那麼 modal 元素將追加到這些節點以後,有興趣能夠本身試一下。學習

與組件一塊兒使用

其實使用在組件上和普通的 dom 元素並無什麼區別,組件中的節點將被渲染到指定的dom節點中(body或者指定ID)this

const app = Vue.createApp({
  ...
  template: `
    <div class="box" id="box">
      <button @click="handleShowModal">顯示模態窗口</button>
      <teleport to="body">
         <child-component :name="name"/>
       </teleport>
    </div>
  `
}
app.component('child-component',{
    props:['name']
    template: `<div class='modal'>{{name}}</div>`
})

即便被渲染到不一樣的節點,它仍和普通子組件同樣,接收父組件傳輸的數據,並無由於渲染節點改變而改變。code

對同一目標使用多個 teleport

<teleport to="#modals">
  <div>A</div>
</teleport>
<teleport to="#modals">
  <div>B</div>
</teleport>

結果以下:

-- #modal
    -- A
    -- B

因此上面我一直強調,使用 teleport 是將包裹元素追加到指定節點,因此上面兩個 teleport 將依次追加到 #modal 上。

總結

teleport多應用於邏輯屬於該組件,而從技術角度講,卻要把它移動到其餘節點(body或者指定ID的元素) 裏。最多見的場景就是建立一個包含全屏模式的組件,邏輯存在於組件內,可是基於css樣式,卻要把他移動到 body 元素上。

相關文章
相關標籤/搜索