中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

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

vue基于Teleport如何實現Modal組件

發布時間:2021-05-31 12:53:29 來源:億速云 閱讀:162 作者:小新 欄目:開發技術

這篇文章將為大家詳細講解有關vue基于Teleport如何實現Modal組件,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1.認識Teleport

像我們如果寫Modal組件、Message組件、Loading組件這種全局式組件,沒有Teleport的話,將它們引入一個.vue文件中,則他們的HTML結構會被添加到組件模板中,這是不夠完美的。

  • 沒有Teleport

vue基于Teleport如何實現Modal組件

  • 有Teleport

vue基于Teleport如何實現Modal組件

下面就實戰介紹一下如何用Teleport開發Modal組件

2.Teleport的基本用法

Teleport的寫法十分簡單,只需要用<Teleport></Teleport>將內容包裹,并用to指定將HTML掛到哪個父節點下,就可以啦。

<teleport to="#modal">
內容
</teleport>

3.第一步優化

如果我們在代碼中將Teleport要掛載的DOM寫死,那么每創建一個全局式組件,就需要有一個DOM節點,會越來越多,并且一直存在,這樣的寫法不是很優雅。比較好的解決方案就是:

  • 在創建組件的時候,動態創建一個dom節點document.createElement(),

  • 并添加到body中,document.body.appendChild(),

  • 在組件卸載的時候銷毀這個dom document.body.removeChild(),

setup(){
  const node = document.createElement('div')
  node.id = 'modal'
  document.body.appendChild(node)
  onUnmounted(() => {
    document.body.removeChild(node)
  })
}

4.第二步優化

如果我們后續還要添加Message組件,Loading組件等功能,同樣要用到Teleport,在每一個組件內部都寫這么一段代碼,實在有點冗余,vue3使我們能夠很方便的將邏輯功能提取出來,從而達到邏輯復用的目的。

我們在src-hooks文件夾下創建useDOMCreate.ts文件,來封裝這一塊邏輯

// hooks/useDOMCreate.ts
import { onUnmounted } from 'vue'

function useDOMCreate(nodeId:string):void {
  const node = document.createElement('div')
  node.id = nodeId
  document.body.appendChild(node)
  onUnmounted(() => {
    document.body.removeChild(node)
  })
}
export default useDOMCreate

使用:

import useDOMCreate from '../hooks/useDOMCreate'
setup(props, ctx) {
    useDOMCreate('modal')
}

5.實現Modal組件

具體封裝Modal組件的細節這里就不講啦,也沒有什么復雜的邏輯。直接上代碼。

//Modal.vue
<template>
  <teleport to="#modal">
    <div class="modal d-block" tabindex="-1" v-if="isVisible">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h6 class="modal-title">{{title}}</h6>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
              <span aria-hidden="true" @click="onClose">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <slot></slot>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal"  @click="onClose">取消</button>
            <button type="button" class="btn btn-primary"  @click="onConfirm">確定</button>
          </div>
        </div>
      </div>
    </div>
  </teleport>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import useDOMCreate from '../hooks/useDOMCreate'
export default defineComponent({
  name: 'Modal',
  emits: ['model-close', 'model-confirm'],
  props: {
    title: {
      type: String,
      default: ''
    },
    isVisible: {
      type: Boolean,
      default: false
    }
  },
  setup(props, ctx) {
    useDOMCreate('modal')
    const onClose = () => {
      ctx.emit('model-close')
    }
    const onConfirm = () => {
      ctx.emit('model-confirm')
    }
    return {
      onClose,
      onConfirm
    }
  }
})
</script>

使用示例

<template>
  <div class="post-detail-page">
    <button type="button" class="btn btn-danger" @click="handleDelete">刪除</button>
    <modal title='是否確認刪除?' :isVisible="modalVisible" @model-close="hanldeModalClose" @model-confirm="handleModalConfim">
      <p>確認要刪除這篇文章嗎?</p>
    </modal>
  </div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import Modal from '../components/Modal.vue'

export default defineComponent({
  name: 'post-detail',
  components: { Modal },
  setup() {
    const modalVisible = ref(false)
    const handleDelete = () => {
      modalVisible.value = true
    }
    const hanldeModalClose = () => {
      modalVisible.value = false
    }
    const handleModalConfim = () => {
      modalVisible.value = false
      ...
     / /后續邏輯處理
    }
    return {
      hanldeModalClose,
      handleModalConfim,
      handleDelete,
      modalVisible
    }
  }
})
</script>

關于“vue基于Teleport如何實現Modal組件”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細節

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

AI

宜兰市| 古交市| 秦皇岛市| 铁力市| 衡阳县| 诸城市| 林芝县| 田林县| 龙游县| 谢通门县| 义马市| 舒城县| 靖远县| 湖北省| 阳曲县| 神木县| 托克托县| 眉山市| 禹城市| 隆子县| 隆化县| 新巴尔虎右旗| 应城市| 若尔盖县| 库车县| 苏州市| 乌兰察布市| 赣榆县| 鹤岗市| 清苑县| 威宁| 达州市| 南澳县| 寻乌县| 屯留县| 沙河市| 丰都县| 文成县| 娱乐| 洛阳市| 榆中县|