自定义弹窗组件Dialog详解
在Vue.js前端开发中,弹窗组件是常见的交互元素之一。为了提高开发效率并保持代码的可维护性,我们可以创建自定义弹窗组件。本文将详细解析Vue.js自定义弹窗组件Dialog的实现原理和使用示例,并提供相关代码和注释。
文章目录
一、为什么要实现这么一个自定义的弹框组件?
项目中大量的模块因字段都比较少,因此添加和编辑用弹框的形式更加方便,但是UI的设计和现用的组件库的弹框组件差异比较大,只能自己动手封装这么一个组件了。
二、使用步骤
1.创建组件对应的文件
组件代码如下:
<template>
<div v-if="showDialog">
<transition name="fade" appear>
<div class="modal-overlay"></div>
</transition>
<transition name="pop" appear>
<div class="modal" role="dialog" :style="{ width: `${width}px` }">
<div class="model-title">
<div class="title-text">
<span>{{ title }}</span>
<div class="icon-close" v-if="showClose">
<i class="el-icon-close" @click="close"></i>
</div>
</div>
<div class="semiel-lipse"></div>
</div>
<div class="model-body">
<slot></slot>
</div>
<div class="footer_btn">
<div class="dis_in_center" v-if="showConfimButton">
<el-button
:disabled="disabled"
:type="confimBtnType"
:loading="confimBtnLoading"
:size="size"
@click="confim"
>
{{ confimText }}
</el-button>
</div>
<div class="dis_in_center right-btn" :class="{ margin_left_20: showCancelButton }" v-if="showCancelButton">
<el-button plain :type="cancelType" :size="size" @click="close">{{ cancelText }}</el-button>
</div>
</div>
</div>
</transition>
</div>
</template>
<script>
export default {
name: 'CustomDialog',
components: {},
model: {
prop: 'showDialog',
event: 'change'
},
props: {
// 弹框的显示隐藏
showDialog: {
type: Boolean,
default: false
},
// 底部按钮大小
size: {
type: String,
default: 'medium'
},
// 宽度设置
width: {
type: [String, Number],
default: '600'
},
// 是否显示右上角的关闭按钮
showClose: {
type: Boolean,
default: true
},
// 弹框标题
title: {
type: String,
default: '标题'
},
// 确认按钮
confimText: {
type: String,
default: '保存'
},
// 确认按钮loading
confimBtnLoading: {
type: Boolean,
default: false
},
// 是否显示确认按钮
showConfimButton: {
type: Boolean,
default: true
},
// 是否显示取消按钮
showCancelButton: {
type: Boolean,
default: true
},
// 是否禁用确认按钮
disabled: {
type: Boolean,
default: false
},
// 确认按钮类型
confimBtnType: {
type: String,
default: 'primary'
},
// 取消按钮类型
cancelType: {
type: String,
default: 'info'
},
// 取消按钮文本
cancelText: {
type: String,
default: '取消'
},
// 关闭按钮前的事件处理
beforeClose: {
type: Function,
default: () => {
return true;
}
}
},
methods: {
close() {
const data = this.beforeClose();
if (!data) return;
this.$emit('change', false);
},
confim() {
this.$emit('confim', false);
}
}
};
</script>
<style scoped>
.modal {
position: absolute;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
height: fit-content;
box-shadow: 0px 5px 15px 0px rgba(255, 102, 0, 0.3);
min-width: 400px;
border-radius: 1rem;
overflow: hidden;
background: #fff;
z-index: 999;
border-radius: 4px;
transform: none;
}
.model-body {
padding: 2rem;
min-height: 2rem;
max-height: 50vh;
overflow-y: auto;
}
.model-title {
position: relative;
height: 64px;
text-align: center;
overflow: hidden;
line-height: 64px;
width: 100%;
color: #fff;
font-size: 18px;
}
.semiel-lipse {
position: absolute;
width: 110%;
left: -5%;
height: 150%;
top: -50%;
background: rgba(255, 102, 0, 0.8);
border-radius: 0% 0% 50% 50%;
}
.title-text {
position: relative;
z-index: 1000;
}
.icon-close {
position: absolute;
right: 42px;
top: 0;
line-height: 44px;
}
.icon-close i {
cursor: pointer;
}
.modal-overlay {
content: '';
position: absolute;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 998;
background: rgba(0, 0, 0, 0.4);
}
.footer_btn {
text-align: center;
padding-bottom: 20px;
padding-top: 20px;
border-top: 1px solid #f5f5f5;
}
.dis_in_center {
display: inline-block;
vertical-align: middle;
}
.right-btn {
margin-left: 20px;
}
/* ---------------------------------- */
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.4s linear;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.pop-enter-active,
.pop-leave-active {
transition: transform 0.4s cubic-bezier(0.5, 0, 0.5, 1), opacity 0.4s linear;
}
.pop-enter,
.pop-leave-to {
opacity: 0;
transform: scale(0.3) translateY(-50%);
}
</style>
2.CustomDialog 自定义弹框组件详解
下面对CustomDialog组件的关键部分进行详细解释:
模板部分
title
属性绑定了弹窗的标题,可以通过父组件传递属性进行自定义。showDialog
属性控制弹窗的显示与隐藏,我们使用了双向绑定,即通过v-model将组件内部的visible属性与外部的value属性进行关联。width
属性控制弹窗的宽度,可以根据实际需求进行自定义。@close
事件绑定了$emit('change')
,当取消或者关闭按钮时触发,向父组件传递取消按钮被点击的信号。@confim
事件绑定了$emit('confim')
,当点击确认按钮时触发,向父组件传递取消按钮被点击的信号showClose
是否显示右上角的关闭按钮
插槽部分
<slot></slot>
标签用于显示弹窗的主要内容,父组件可以在使用标签时插入自定义的内容。
属性部分
- showDialog属性是组件的一个props,用于控制弹窗的显示与隐藏,它的类型是布尔型,默认值为false。
- confimText和cancelText属性分别用于设置保存按钮和取消按钮的文案,默认值分别为"确定"和"取消"。
- showConfimButton和showCancelButton属性分别用于设置保存按钮和取消按钮的显示和隐藏,默认值都显示。
- confimBtnType和cancelType属性分别用于设置保存按钮和取消按钮的类型,保存按钮默认值都为primary,取消按钮默认值都为info。
- title属性用于设置弹窗的标题,默认值为空字符串。
- width属性用于设置弹窗的宽度,默认值为"600px"。
- beforeClose 关闭按钮前的事件处理
演示截图和代码
在使用ByDialog组件时,我们可以通过传递不同的属性和事件监听器来实现定制化的弹窗效果。下面是一个使用示例:
<template>
<custom-dialog
v-model="showDialog"
width="500"
confimText="确认"
cancelType="primary"
:confimBtnLoading="confimBtnLoading"
@confim="confirmModel"
@change="changeModel"
title="dialog弹框"
>
<div>中间内容</div>
</custom-dialog>
</template>
<script>
export default {
name: 'upload-dialog',
model: {
prop: 'value',
event: 'change'
},
data() {
return {
showDialog: false,
confimBtnLoading: false
};
},
methods: {
/**
* @desc 上传弹框关闭事件
*/
changeModel() {
this.showDialog = false;
},
/**
* @desc 确定按钮事件
*/
confirmModel() {
this.confimBtnLoading= true;
// 处理业务逻辑相关的代码
this.confimBtnLoading= false;
this.showDialog= false;
}
}
};
</script>
总结
通过自定义弹窗组件ByDialog,我们可以在Vue.js应用中创建高度定制化的弹窗功能。通过属性、事件和插槽的灵活运用,我们可以实现各种弹窗样式和交互效果。