vue基于Teleport實(shí)現(xiàn)Modal組件
1.認(rèn)識(shí)Teleport
像我們?nèi)绻麑慚odal組件、Message組件、Loading組件這種全局式組件,沒(méi)有Teleport的話,將它們引入一個(gè).vue文件中,則他們的HTML結(jié)構(gòu)會(huì)被添加到組件模板中,這是不夠完美的。
- 沒(méi)有Teleport
- 有Teleport
下面就實(shí)戰(zhàn)介紹一下如何用Teleport開(kāi)發(fā)Modal組件
2.Teleport的基本用法
Teleport的寫法十分簡(jiǎn)單,只需要用<Teleport></Teleport>將內(nèi)容包裹,并用to指定將HTML掛到哪個(gè)父節(jié)點(diǎn)下,就可以啦。
<teleport to="#modal"> 內(nèi)容 </teleport>
3.第一步優(yōu)化
如果我們?cè)诖a中將Teleport要掛載的DOM寫死,那么每創(chuàng)建一個(gè)全局式組件,就需要有一個(gè)DOM節(jié)點(diǎn),會(huì)越來(lái)越多,并且一直存在,這樣的寫法不是很優(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使我們能夠很方便的將邏輯功能提取出來(lái),從而達(dá)到邏輯復(fù)用的目的。
我們?cè)趕rc-hooks文件夾下創(chuàng)建useDOMCreate.ts文件,來(lái)封裝這一塊邏輯
// 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é)這里就不講啦,也沒(méi)有什么復(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組件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- Vue3中內(nèi)置組件Teleport的基本使用與典型案例
- Vue中代碼傳送(teleport)的實(shí)現(xiàn)
- Vue3?源碼解讀之?Teleport?組件使用示例
- vue3新增Teleport的問(wèn)題
- 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)文章
Vue項(xiàng)目中如何使用Axios封裝http請(qǐng)求詳解
這篇文章主要給大家介紹了關(guān)于Vue項(xiàng)目中如何使用Axios封裝http請(qǐng)求的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10vue.js使用v-model實(shí)現(xiàn)表單元素(input) 雙向數(shù)據(jù)綁定功能示例
這篇文章主要介紹了vue.js使用v-model實(shí)現(xiàn)表單元素(input) 雙向數(shù)據(jù)綁定功能,結(jié)合完整實(shí)例形式分析了v-model實(shí)現(xiàn)表單input元素?cái)?shù)據(jù)雙向綁定相關(guān)操作技巧,需要的朋友可以參考下2019-03-03vue v-for循環(huán)重復(fù)數(shù)據(jù)無(wú)法添加問(wèn)題解決方法【加track-by=''索引''】
這篇文章主要介紹了vue v-for循環(huán)重復(fù)數(shù)據(jù)無(wú)法添加問(wèn)題解決方法,結(jié)合實(shí)例形式分析了vue.js通過(guò)在v-for循環(huán)中添加track-by='索引'解決重復(fù)數(shù)據(jù)無(wú)法添加問(wèn)題相關(guān)操作技巧,需要的朋友可以參考下2019-03-03vue2中watch的用法(通俗易懂,簡(jiǎn)單明了)
這篇文章主要給大家介紹了關(guān)于vue2中watch用法的相關(guān)資料,通過(guò)watch監(jiān)聽(tīng)器,我們可以實(shí)時(shí)監(jiān)控?cái)?shù)據(jù)的變化,并且在數(shù)據(jù)發(fā)生改變時(shí)進(jìn)行相應(yīng)的操作,需要的朋友可以參考下2023-09-09Vue彈窗Dialog最佳使用方案實(shí)戰(zhàn)
這篇文章主要為大家介紹了極度舒適的Vue彈窗Dialog最佳使用方案實(shí)戰(zhàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過(guò)配置文件修改)
這篇文章主要介紹了關(guān)于axios配置多個(gè)請(qǐng)求地址(打包后可通過(guò)配置文件修改),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09Vue使用Composition?API生成計(jì)算屬性computed
這篇文章主要為大家詳細(xì)介紹了Vue如何使用Composition?API實(shí)現(xiàn)生成計(jì)算屬性computed,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-06-06vue實(shí)現(xiàn)點(diǎn)擊選中,其他的不選中方法
今天小編就為大家分享一篇vue實(shí)現(xiàn)點(diǎn)擊選中,其他的不選中方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-09-09