Vue3+Element Plus實(shí)現(xiàn)自定義彈窗組件的全屏功能
組件概述
我們將構(gòu)建一個(gè)名為 Dialog 的 Vue 組件,該組件具備以下特性:
- 自定義頭部,包括全屏和關(guān)閉按鈕
- 支持全屏和還原功能
- 可配置的彈窗尺寸和位置
- 拖拽功能(可選)
- 動(dòng)態(tài)內(nèi)容區(qū)域高度
以下是實(shí)現(xiàn)自定義彈窗組件的詳細(xì)步驟和代碼示例。
組件實(shí)現(xiàn)
1. 組件模板
我們使用 el-dialog 作為基礎(chǔ)組件,并自定義了 header 插槽以添加全屏按鈕和關(guān)閉圖標(biāo)。
<template>
<el-dialog
:dialogHeight="dialogHeight"
:title="dialogTitle"
class="dialog min-w-70"
v-model="dialogVisible"
append-to-body
:modal="dialogModal"
:fullscreen="fullscreen"
:close-on-click-modal="dialogClickModalClose"
:draggable="dialogDraggable"
:show-close="false"
:width="dialogWidth"
:align-center="dialogAlignCenter"
:center="dialogContentCenter"
@open="open"
@close="close"
>
<template #header>
<div class="flex justify-between items-content">
<div class="titleClass">{{ dialogTitle }}</div>
<div class="icon-content">
<!-- <el-icon class="single-uploader__icon text-[12px]">
<i-ep-minus v-if="fullscreen" />
<i-ep-plus v-else />
</el-icon>-->
<div :title="!fullscreen ? '全屏' : '還原'">
<svg-icon
class="icon-item-content"
v-if="showExpand"
@click="zoom"
:icon-class="fullscreen ? 'fullscreen-exit' : 'fullscreen'"
/>
</div>
<div title="關(guān)閉">
<el-icon
v-if="showClose"
@click="close"
title="關(guān)閉"
class="single-uploader__icon icon-item-content"
>
<i-ep-close />
</el-icon>
</div>
</div>
</div>
</template>
<div :style="{ height: dialogBodyHeight }" class="overflow-auto">
<slot></slot>
</div>
<template #footer v-if="dialogFooterBtn">
<el-button type="primary" @click="SaveSubmit">確 定</el-button>
<el-button @click="CloseSubmit">取 消</el-button>
</template>
</el-dialog>
</template>
2. 組件腳本
在腳本部分,我們定義了組件的 props、slots 和 emits,以及一些必要的響應(yīng)式數(shù)據(jù)和函數(shù)。
<script setup lang="ts">
// 【接口】接受傳參字段
interface IProps {
// 是否顯示 Dialog
visible: boolean;
// 對(duì)話框的標(biāo)題
dialogTitle?: string;
// 內(nèi)容區(qū)域高度
dialogHeight?: string;
// 對(duì)話框的寬度
dialogWidth?: string;
// 是否需要遮罩層
dialogModal?: boolean;
// 是否水平垂直對(duì)齊對(duì)話框
dialogAlignCenter?: boolean;
// 是否讓 Dialog 的 header 和 footer 部分居中排列
dialogContentCenter?: boolean;
// 是否可以通過(guò)點(diǎn)擊 modal 關(guān)閉 Dialog
dialogClickModalClose?: boolean;
// 為 Dialog 啟用可拖拽功能
dialogDraggable?: boolean;
// 是否顯示底部按鈕
dialogFooterBtn?: boolean;
// 是否顯示全屏按鈕
showExpand?: boolean;
// 是否顯示關(guān)閉按鈕
showClose?: boolean;
}
// 初始化默認(rèn)參數(shù)
const props = withDefaults(defineProps<IProps>(), {
dialogTitle: "默認(rèn)標(biāo)題",
dialogWidth: "40%",
dialogHeight: "auto",
dialogModal: true,
dialogAlignCenter: false,
dialogContentCenter: false,
dialogClickModalClose: false,
dialogDraggable: false,
dialogFooterBtn: true,
showExpand: false,
showClose: true,
});
const emit = defineEmits([
"save",
"cancellation",
"open",
"close",
"zoom",
"update:visible",
]);
const dialogVisible = useVModel(props, "visible", emit);
let fullscreen = ref(false);
const dialogBodyHeight = ref<string | number>(); // 初始值為字符串類型
// watch監(jiān)聽(tīng)
watch(
[() => props.visible, () => props.dialogHeight, () => props.dialogFooterBtn],
() => {
nextTick(() => {
menuDialogZoom();
});
},
{ deep: true, immediate: true }
);
// 保存提交回調(diào)函數(shù)
const SaveSubmit = () => {
emit("save"); //emit方法供父級(jí)組件調(diào)用
};
// 取消保存回調(diào)函數(shù)
const CloseSubmit = () => {
emit("cancellation"); //emit方法供父級(jí)組件調(diào)用
};
// 打開(kāi)事件回調(diào)函數(shù)
const open = () => {
emit("open"); //emit方法供父級(jí)組件調(diào)用
};
// 關(guān)閉事件回調(diào)函數(shù)(當(dāng)顯示頭部關(guān)閉按鈕時(shí)需調(diào)用該回調(diào)函數(shù)方法 -> dialogShowClose = true 反之)
const close = () => {
emit("close"); //emit方法供父級(jí)組件調(diào)用
};
// 縮放彈窗
const zoom = () => {
fullscreen.value = !fullscreen.value;
menuDialogZoom();
console.log(fullscreen.value);
emit("zoom", fullscreen.value); //emit方法供父級(jí)組件調(diào)用
};
/* 分配權(quán)限縮放彈窗 */
const menuDialogZoom = () => {
if (props.visible && fullscreen.value && props.dialogFooterBtn) {
dialogBodyHeight.value = "calc(100vh - 120px)";
} else if (props.visible && fullscreen.value && !props.dialogFooterBtn) {
dialogBodyHeight.value = "calc(100vh - 80px)";
} else {
dialogBodyHeight.value = props.dialogHeight;
}
};
</script>
3. 組件樣式
<style scoped>
.titleClass {
font-weight: bold;
}
.icon-content {
display: flex;
align-items: center;
}
.icon-item-content {
display: flex;
align-items: center;
justify-content: center;
color: #909399;
}
.icon-item-content:nth-child(1) {
margin-right: 10px;
}
.icon-item-content:hover {
color: #1f6feb;
cursor: pointer;
}
.single-uploader__icon {
font-size: 18px;
}
</style>
4. 使用案例
以下是如何在父組件中使用 Dialog 組件的示例,包括如何傳遞參數(shù)和處理事件。
<Dialog dialogHeight="350px" v-model:visible="menuDialogVisible" :dialogTitle="'【' + checkedRole.name + '】權(quán)限分配'" :dialogDraggable="true" dialogWidth="30%" @close="menuDialogVisible = false" @save="handleRoleMenuSubmit" @cancellation="menuDialogVisible = false" > 內(nèi)容區(qū)域 </Dialog>
5. 彈窗相關(guān)數(shù)據(jù)
定義了控制彈窗顯示的響應(yīng)式數(shù)據(jù)。
let menuDialogVisible = ref(false);
關(guān)鍵功能實(shí)現(xiàn)
自定義頭部
我們通過(guò) header 插槽來(lái)自定義彈窗的頭部,增加了全屏切換按鈕和關(guān)閉按鈕。
<template #header> <!-- 省略部分代碼,詳見(jiàn)完整代碼示例 --> </template>
全屏和還原功能
通過(guò)點(diǎn)擊全屏按鈕,我們可以切換彈窗的全屏狀態(tài)。這一功能通???修改 fullscreen 響應(yīng)式數(shù)據(jù)實(shí)現(xiàn)。
const zoom = () => {
fullscreen.value = !fullscreen.value;
menuDialogZoom();
emit("zoom", fullscreen.value);
};
動(dòng)態(tài)內(nèi)容區(qū)域高度
根據(jù)彈窗的全屏狀態(tài)和是否顯示底部按鈕,我們動(dòng)態(tài)計(jì)算內(nèi)容區(qū)域的高度。
const menuDialogZoom = () => {
// 省略部分代碼,詳見(jiàn)完整代碼示例
};
結(jié)論
通過(guò)以上步驟,我們創(chuàng)建了一個(gè)功能豐富、高度可配置的自定義彈窗組件。這個(gè)組件可以根據(jù)實(shí)際需求調(diào)整尺寸、位置和內(nèi)容,非常適合在復(fù)雜的應(yīng)用場(chǎng)景中使用。希望這篇文章能幫助您在項(xiàng)目中更好地利用 Vue 3 和 Element Plus 庫(kù)。如果您有任何疑問(wèn)或建議,歡迎在評(píng)論區(qū)留言交流。
以上就是Vue3+Element Plus實(shí)現(xiàn)自定義彈窗組件的全屏功能的詳細(xì)內(nèi)容,更多關(guān)于Vue3 Element Plus彈窗組件全屏的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- vue3使用el-radio-group獲取表格數(shù)據(jù)無(wú)法選中問(wèn)題及解決方法
- Vue3實(shí)現(xiàn)Element Plus表格的多選功能與條件操作
- vue3?element?plus?table?selection展示數(shù)據(jù),默認(rèn)選中功能方式
- 基于Vue3和Element Plus實(shí)現(xiàn)可擴(kuò)展的表格組件
- vue3+js+elementPlus使用富文本編輯器@vueup/vue-quill詳細(xì)教程
- vue3 element plus中el-radio選中之后再次點(diǎn)擊取消選中問(wèn)題
相關(guān)文章
Vue結(jié)合openlayers按照經(jīng)緯度坐標(biāo)實(shí)現(xiàn)錨地標(biāo)記及繪制多邊形區(qū)域
OpenLayers是一個(gè)用于開(kāi)發(fā)WebGIS客戶端的JavaScript包,最初基于BSD許可發(fā)行。OpenLayers是一個(gè)開(kāi)源的項(xiàng)目,其設(shè)計(jì)之意是為互聯(lián)網(wǎng)客戶端提供強(qiáng)大的地圖展示功能,包括地圖數(shù)據(jù)顯示與相關(guān)操作,并具有靈活的擴(kuò)展機(jī)制2022-09-09
VUE如何利用vue-print-nb實(shí)現(xiàn)打印功能詳解
這篇文章主要給大家介紹了關(guān)于VUE如何利用vue-print-nb實(shí)現(xiàn)打印功能的相關(guān)資料,文中還給大家介紹了vue-print-nb使用中的常見(jiàn)問(wèn)題,如空白頁(yè),需要的朋友可以參考下2022-04-04
vue數(shù)據(jù)初始化initState的實(shí)例詳解
Vue 實(shí)例在建立的時(shí)候會(huì)運(yùn)行一系列的初始化操作,而在這些初始化操作里面,和數(shù)據(jù)綁定關(guān)聯(lián)最大的是 initState。這篇文章主要介紹了vue數(shù)據(jù)初始化--initState,需要的朋友可以參考下2019-04-04
Vue3封裝ant-design-vue表格的詳細(xì)代碼
這篇文章主要介紹了Vue3封裝ant-design-vue表格,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05
vue響應(yīng)式Object代理對(duì)象的修改和刪除屬性
這篇文章主要為大家介紹了vue響應(yīng)式Object代理對(duì)象的修改和刪除屬性示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
vue學(xué)習(xí)筆記之slot插槽基本用法實(shí)例分析
這篇文章主要介紹了vue學(xué)習(xí)筆記之slot插槽基本用法,結(jié)合實(shí)例形式分析了vue slot插槽基本使用方法與操作注意事項(xiàng),需要的朋友可以參考下2020-02-02

