利用Vue3封裝一個(gè)彈框組件簡(jiǎn)單嗎
總結(jié)放前面:
Tipes: 封裝彈框組件使用了Teleport,避免了組件嵌套可能導(dǎo)致的定位層級(jí)的隱患,還使用了defineProps,defineEmits,插槽增加了組件的拓展性。
???? 前言:
之前一直沒(méi)有自己去封裝過(guò)一個(gè)彈框組件,但是覺(jué)得一個(gè)小小的彈窗組件那不是灑灑水小意思了。然后今天新項(xiàng)目中需要一個(gè)彈窗組件,所以我就做了一個(gè)。不做不要緊一做發(fā)現(xiàn)還是有很多不同的小問(wèn)題,然后就把遇到的問(wèn)題和大佬們分享一下。
開(kāi)始先回顧一下需求,一個(gè)全局使用的公共彈框組件。那么就有幾個(gè)要點(diǎn):公共、全局、彈框,下面我們就針對(duì)這幾個(gè)要點(diǎn)去一點(diǎn)點(diǎn)實(shí)現(xiàn)彈框組件。
????公共????
公共這個(gè)簡(jiǎn)單,相信在座的各位大佬肯定都是手拿把掐,輕輕松松就實(shí)現(xiàn)了。
先實(shí)現(xiàn)一個(gè)主體內(nèi)容,我的方法就是使用插槽和參數(shù)傳遞。例子只是簡(jiǎn)單的傳遞兩個(gè)參數(shù),一個(gè)標(biāo)題內(nèi)容一個(gè)控制打開(kāi)和關(guān)閉的布爾值。主要涉及到Vue3兩個(gè)Api的使用defineProps,defineEmits還有插槽的使用。
<template> <Mask @click="close" /> // 蒙板層 <div class="modal_all" v-if="visible"> <slot name="header"> // 方便頁(yè)面增加定制頭部 <div class="modal_header"> <p class="modal_header_title">{{ title }}</p> <p class="modal_header_img" @click="close"></p> </div> </slot> <div class="modal_content"> <slot></slot> // 開(kāi)放彈框內(nèi)容使用 </div> </div> </template> <script lang="ts" setup> defineProps({ visible: { type: Boolean, default: false, }, title: { type: String, }, }); const emit = defineEmits(['update:visible']); const close = () => { emit('update:visible', false); }; </script> // 樣式省略
????全局????
基本布局差不多了,下面就是全局注冊(cè),目的是為了不用每次使用每次都要引入。
vue2在注冊(cè)全局組件的時(shí)候,直接Vue.component('名稱', 組件)就可以了,那么在vue3中怎么批量注冊(cè)全局組件吶?提供一個(gè)install方法,使用app.use()自動(dòng)調(diào)用。
import Modal from './Modal/Modal.vue'; import Mask from './Modal/Mask.vue'; // 在script setup不能寫(xiě)name,所以在這里加一個(gè) const coms = [ { name: 'Modal', // 使用組件的名稱 compent: Modal, }, { name: 'Mask', compent: Mask, }, ]; export default { install: (app) => { coms.forEach((item) => { app.component(item.name, item.compent); }); }, }; // main.ts import Common from './common/index'; const app = createApp(App); app.use(Common);
????彈框????
其實(shí)彈框組件寫(xiě)到這里已經(jīng)差不多了,那為什么要把彈框這個(gè)單獨(dú)列出來(lái)說(shuō)一下吶?
相信各位大佬在日常工作中也遇到過(guò)定位和層級(jí)的問(wèn)題,如果我們把需要定位的組件嵌套在 Vue 的某個(gè)組件內(nèi)部,因?yàn)閏ss各種層的原因我們?cè)谔幚砬短椎亩ㄎ?、層?jí) 和樣式就會(huì)變得很困難,一不小心就會(huì)出現(xiàn)一些奇奇怪怪的問(wèn)題,那么怎么去避免這個(gè)問(wèn)題?下面就要使用到Vue3中另外一個(gè)傳送門Api:Teleport。
Tipes: Teleport就是將我們的組件掛載到屬性 to 對(duì)應(yīng)的DOM元素中,類似一個(gè)任意門。
先上代碼:
<teleport to="#mask_modal" v-if="visible"> <div class="modal_cent"> <Mask @click="close" /> <div class="modal_all"> <slot name="header"> <div class="header"> <p class="header_title">{{ title }}</p> <p class="header_img" @click="close"></p> </div> </slot> <div> <slot></slot> </div> </div> </div> </teleport>
我們來(lái)看一下這樣寫(xiě)之后的層級(jí):
通過(guò) to 屬性,指定彈框組件渲染的位置與layput組件同級(jí),但是 teleport 的狀態(tài) visible 又是完全由我們調(diào)用的組件控制,就避免了我們?cè)谇短捉M件的時(shí)候定位層級(jí)樣式的問(wèn)題。
???? 至此,一個(gè)簡(jiǎn)單的公共彈框組件已經(jīng)寫(xiě)的差不多了。然后在寫(xiě)這個(gè)組件的過(guò)程中我還是遇到了幾個(gè)不算問(wèn)題的問(wèn)題??。
??????1.script setup中沒(méi)法寫(xiě)name屬性:
如果沒(méi)有用ts的話,可以再寫(xiě)一個(gè)script標(biāo)簽,在里面導(dǎo)出然后寫(xiě)name。如果使用ts,那么這個(gè)方法就行不通就會(huì)報(bào)錯(cuò)。那么就利用我上面寫(xiě)的方法,自己重新定義一下寫(xiě)一個(gè)對(duì)象那樣。
??????2.直接給全局組件加一個(gè)class加樣式不生效:
其實(shí)我們正常寫(xiě)公共組件,在使用的地方想直接在外層控制內(nèi)部容器的樣式,我們可以直接在外面加一個(gè)類名去增加樣式,但是我在寫(xiě)這個(gè)彈框組件的時(shí)候卻一直不生效,找了半天后來(lái)才發(fā)現(xiàn)原來(lái)是因?yàn)槲沂褂昧藅eleport,所以在解析的時(shí)候class不能被繼承。同樣要是組件內(nèi)沒(méi)有一個(gè)根組件同樣會(huì)出現(xiàn)這樣的問(wèn)題。這樣其實(shí)也沒(méi)關(guān)系,我們?cè)诓宀蹆?nèi)寫(xiě)內(nèi)容自動(dòng)撐開(kāi)就可以了,相信各位大佬肯定不會(huì)像我一樣搞這么傻的操作,哈哈。
??????結(jié)語(yǔ):
其實(shí)一個(gè)彈框組件的封裝還是很簡(jiǎn)單的,不過(guò)也算是積累了一點(diǎn)經(jīng)驗(yàn),把自己的項(xiàng)目實(shí)施落地。后面去封裝更加復(fù)雜的組件也會(huì)比較有思路。
到此這篇關(guān)于利用Vue3封裝一個(gè)彈框組件的文章就介紹到這了,更多相關(guān)Vue3封裝彈框組件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 基于Vue3.0開(kāi)發(fā)輕量級(jí)手機(jī)端彈框組件V3Popup的場(chǎng)景分析
- vue移動(dòng)端彈框組件的實(shí)例
- vue教程之toast彈框全局調(diào)用示例詳解
- vue+elementui實(shí)現(xiàn)點(diǎn)擊table中的單元格觸發(fā)事件--彈框
- vue.js中toast用法及使用toast彈框的實(shí)例代碼
- vue多種彈框的彈出形式的示例代碼
- vue+iview寫(xiě)個(gè)彈框的示例代碼
- vue中簡(jiǎn)單彈框dialog的實(shí)現(xiàn)方法
- vue自定義全局組件實(shí)現(xiàn)彈框案例
相關(guān)文章
Vue富文本插件(quill-editor)的使用及說(shuō)明
這篇文章主要介紹了Vue富文本插件(quill-editor)的使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。2023-02-02一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對(duì)象觀測(cè))
這篇文章主要介紹了一步一步實(shí)現(xiàn)Vue的響應(yīng)式(對(duì)象觀測(cè)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09vue-content-loader內(nèi)容加載器的使用方法
這篇文章主要介紹了vue-content-loader內(nèi)容加載器的使用方法,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08vue 使用 vue-pdf 實(shí)現(xiàn)pdf在線預(yù)覽的示例代碼
這篇文章主要介紹了vue 使用 vue-pdf 實(shí)現(xiàn)pdf在線預(yù)覽的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04vue-cli3項(xiàng)目打包后自動(dòng)化部署到服務(wù)器的方法
這篇文章主要介紹了vue-cli3項(xiàng)目打包后自動(dòng)化部署到服務(wù)器的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Vue實(shí)現(xiàn)開(kāi)心消消樂(lè)游戲算法
這篇文章主要介紹了使用Vue寫(xiě)一個(gè)開(kāi)心消消樂(lè)游戲,游戲算法在文中給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10vuex頁(yè)面刷新數(shù)據(jù)丟失問(wèn)題的四種解決方式
vuex是大家使用vue時(shí)大多數(shù)都會(huì)選擇的,但是當(dāng)頁(yè)面刷新之后vuex數(shù)據(jù)會(huì)丟失,下面這篇文章主要給大家介紹了關(guān)于vuex頁(yè)面刷新數(shù)據(jù)丟失問(wèn)題的四種解決方式,需要的朋友可以參考下2022-02-02vue-cli4.x創(chuàng)建企業(yè)級(jí)項(xiàng)目的方法步驟
這篇文章主要介紹了vue-cli4.x創(chuàng)建企業(yè)級(jí)項(xiàng)目的方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06vue 中this.$set 動(dòng)態(tài)綁定數(shù)據(jù)的案例講解
這篇文章主要介紹了vue 中this.$set 動(dòng)態(tài)綁定數(shù)據(jù)的案例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-01-01