利用Vue3封裝一個彈框組件簡單嗎
總結放前面:
Tipes: 封裝彈框組件使用瞭Teleport,避免瞭組件嵌套可能導致的定位層級的隱患,還使用瞭defineProps,defineEmits,插槽增加瞭組件的拓展性。
🌲🌲 前言:
之前一直沒有自己去封裝過一個彈框組件,但是覺得一個小小的彈窗組件那不是灑灑水小意思瞭。然後今天新項目中需要一個彈窗組件,所以我就做瞭一個。不做不要緊一做發現還是有很多不同的小問題,然後就把遇到的問題和大佬們分享一下。
開始先回顧一下需求,一個全局使用的公共彈框組件。那麼就有幾個要點:公共、全局、彈框,下面我們就針對這幾個要點去一點點實現彈框組件。
🍬🍬公共🍬🍬
公共這個簡單,相信在座的各位大佬肯定都是手拿把掐,輕輕松松就實現瞭。
先實現一個主體內容,我的方法就是使用插槽和參數傳遞。例子隻是簡單的傳遞兩個參數,一個標題內容一個控制打開和關閉的佈爾值。主要涉及到Vue3兩個Api的使用defineProps,defineEmits還有插槽的使用。
<template> <Mask @click="close" /> // 蒙板層 <div class="modal_all" v-if="visible"> <slot name="header"> // 方便頁面增加定制頭部 <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> // 開放彈框內容使用 </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> // 樣式省略
🍬🍬全局🍬🍬
基本佈局差不多瞭,下面就是全局註冊,目的是為瞭不用每次使用每次都要引入。
vue2在註冊全局組件的時候,直接Vue.component(‘名稱’, 組件)就可以瞭,那麼在vue3中怎麼批量註冊全局組件吶?提供一個install方法,使用app.use()自動調用。
import Modal from './Modal/Modal.vue'; import Mask from './Modal/Mask.vue'; // 在script setup不能寫name,所以在這裡加一個 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);
🍬🍬彈框🍬🍬
其實彈框組件寫到這裡已經差不多瞭,那為什麼要把彈框這個單獨列出來說一下吶?
相信各位大佬在日常工作中也遇到過定位和層級的問題,如果我們把需要定位的組件嵌套在 Vue 的某個組件內部,因為css各種層的原因我們在處理嵌套的定位、層級 和樣式就會變得很困難,一不小心就會出現一些奇奇怪怪的問題,那麼怎麼去避免這個問題?下面就要使用到Vue3中另外一個傳送門Api:Teleport。
Tipes: Teleport就是將我們的組件掛載到屬性 to 對應的DOM元素中,類似一個任意門。
先上代碼:
<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>
我們來看一下這樣寫之後的層級:
通過 to 屬性,指定彈框組件渲染的位置與layput組件同級,但是 teleport 的狀態 visible 又是完全由我們調用的組件控制,就避免瞭我們在嵌套組件的時候定位層級樣式的問題。
🌼🌼 至此,一個簡單的公共彈框組件已經寫的差不多瞭。然後在寫這個組件的過程中我還是遇到瞭幾個不算問題的問題😅。
❗️❗️❗️1.script setup中沒法寫name屬性:
如果沒有用ts的話,可以再寫一個script標簽,在裡面導出然後寫name。如果使用ts,那麼這個方法就行不通就會報錯。那麼就利用我上面寫的方法,自己重新定義一下寫一個對象那樣。
❗️❗️❗️2.直接給全局組件加一個class加樣式不生效:
其實我們正常寫公共組件,在使用的地方想直接在外層控制內部容器的樣式,我們可以直接在外面加一個類名去增加樣式,但是我在寫這個彈框組件的時候卻一直不生效,找瞭半天後來才發現原來是因為我使用瞭teleport,所以在解析的時候class不能被繼承。同樣要是組件內沒有一個根組件同樣會出現這樣的問題。這樣其實也沒關系,我們在插槽內寫內容自動撐開就可以瞭,相信各位大佬肯定不會像我一樣搞這麼傻的操作,哈哈。
🎉🎉🎉結語:
其實一個彈框組件的封裝還是很簡單的,不過也算是積累瞭一點經驗,把自己的項目實施落地。後面去封裝更加復雜的組件也會比較有思路。
到此這篇關於利用Vue3封裝一個彈框組件的文章就介紹到這瞭,更多相關Vue3封裝彈框組件內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Vue3內置組件Teleport使用方法詳解
- vue3中單文件組件<script setup>實例詳解
- vue基於Teleport實現Modal組件
- 詳解Vue新增內置組件的使用
- Vue3常用的通訊方式總結與實例代碼