vue基于Teleport實(shí)現(xiàn)Modal組件
1.認(rèn)識Teleport
像我們?nèi)绻麑慚odal組件、Message組件、Loading組件這種全局式組件,沒有Teleport的話,將它們引入一個(gè).vue文件中,則他們的HTML結(jié)構(gòu)會(huì)被添加到組件模板中,這是不夠完美的。
- 沒有Teleport

- 有Teleport

下面就實(shí)戰(zhàn)介紹一下如何用Teleport開發(fā)Modal組件
2.Teleport的基本用法
Teleport的寫法十分簡單,只需要用<Teleport></Teleport>將內(nèi)容包裹,并用to指定將HTML掛到哪個(gè)父節(jié)點(diǎn)下,就可以啦。
<teleport to="#modal"> 內(nèi)容 </teleport>
3.第一步優(yōu)化
如果我們在代碼中將Teleport要掛載的DOM寫死,那么每創(chuàng)建一個(gè)全局式組件,就需要有一個(gè)DOM節(jié)點(diǎn),會(huì)越來越多,并且一直存在,這樣的寫法不是很優(yōu)雅。比較好的解決方案就是:
- 在創(chuàng)建組件的時(shí)候,動(dòng)態(tài)創(chuàng)建一個(gè)dom節(jié)點(diǎn)document.createElement(),
- 并添加到body中,document.body.appendChild(),
- 在組件卸載的時(shí)候銷毀這個(gè)dom document.body.removeChild(),
setup(){
const node = document.createElement('div')
node.id = 'modal'
document.body.appendChild(node)
onUnmounted(() => {
document.body.removeChild(node)
})
}
4.第二步優(yōu)化
如果我們后續(xù)還要添加Message組件,Loading組件等功能,同樣要用到Teleport,在每一個(gè)組件內(nèi)部都寫這么一段代碼,實(shí)在有點(diǎn)冗余,vue3使我們能夠很方便的將邏輯功能提取出來,從而達(dá)到邏輯復(fù)用的目的。
我們在src-hooks文件夾下創(chuàng)建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.實(shí)現(xiàn)Modal組件
具體封裝Modal組件的細(xì)節(jié)這里就不講啦,也沒有什么復(fù)雜的邏輯。直接上代碼。
//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">
<h5 class="modal-title">{{title}}</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true" @click="onClose">×</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='是否確認(rèn)刪除?' :isVisible="modalVisible" @model-close="hanldeModalClose" @model-confirm="handleModalConfim">
<p>確認(rèn)要?jiǎng)h除這篇文章嗎?</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
...
/ /后續(xù)邏輯處理
}
return {
hanldeModalClose,
handleModalConfim,
handleDelete,
modalVisible
}
}
})
</script>
以上就是vue基于Teleport實(shí)現(xiàn)Modal組件的詳細(xì)內(nèi)容,更多關(guān)于vue Teleport實(shí)現(xiàn)Modal組件的資料請關(guān)注腳本之家其它相關(guān)文章!
- Vue3中內(nèi)置組件Teleport的基本使用與典型案例
- Vue中代碼傳送(teleport)的實(shí)現(xiàn)
- Vue3?源碼解讀之?Teleport?組件使用示例
- vue3新增Teleport的問題
- Vue中使用Teleport的方法示例
- vue2如何實(shí)現(xiàn)vue3的teleport
- vue3 teleport的使用案例詳解
- Vue3內(nèi)置組件Teleport使用方法詳解
- 詳解Vue3中Teleport的使用
- vue3 Teleport瞬間移動(dòng)函數(shù)使用方法詳解
- 詳解Vue3 Teleport 的實(shí)踐及原理
- Vue內(nèi)置組件Teleport的使用
相關(guān)文章
Elementui表格組件+sortablejs實(shí)現(xiàn)行拖拽排序的示例代碼
這篇文章主要介紹了Elementui表格組件+sortablejs實(shí)現(xiàn)行拖拽排序,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Vue3使用element-plus實(shí)現(xiàn)彈窗效果
本文主要介紹了Vue3使用element-plus實(shí)現(xiàn)彈窗效果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
vue treeselect獲取當(dāng)前選中項(xiàng)的label實(shí)例
這篇文章主要介紹了vue treeselect獲取當(dāng)前選中項(xiàng)的label實(shí)例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08
Vue實(shí)現(xiàn)微信小程序中預(yù)覽文件的縮放功能
在微信小程序中,默認(rèn)情況下,文件預(yù)覽功能不支持文檔縮放,導(dǎo)致用戶在遇到小字體時(shí)難以清晰閱讀,為了解決這一問題并提升用戶體驗(yàn),實(shí)現(xiàn)文檔的縮放功能至關(guān)重要,所以本文2024-12-12
在vue中實(shí)現(xiàn)點(diǎn)擊選擇框阻止彈出層消失的方法
今天小編就為大家分享一篇在vue中實(shí)現(xiàn)點(diǎn)擊選擇框阻止彈出層消失的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-09-09

