在 Vue 中封装 UI 组件是非常常见的操作,可以提高开发效率和代码复用性。本文将介绍如何仿照 Element UI 的弹窗组件,封装自己的 alert、confirm 弹窗组件。
创建弹窗组件
1. Dialog.vue 组件代码
<template>
<transition name="dialog-fade">
<div class="dialog-mask" v-if="visible">
<div class="dialog-container">
<div class="dialog-header">{{ title }}</div>
<div class="dialog-body">{{ message }}</div>
<div class="dialog-footer">
<button class="dialog-btn dialog-cancel" @click="handleCancel">{{ cancelButtonText }}</button>
<button class="dialog-btn dialog-confirm" @click="handleConfirm">{{ confirmButtonText }}</button>
</div>
</div>
</div>
</transition>
</template>
<script>
export default {
name: 'Dialog',
props: {
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
message: {
type: String,
default: ''
},
confirmButtonText: {
type: String,
default: '确定'
},
cancelButtonText: {
type: String,
default: '取消'
}
},
methods: {
handleCancel() {
this.$emit('cancel')
},
handleConfirm() {
this.$emit('confirm')
}
}
}
</script>
<style scoped>
.dialog-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
}
.dialog-container {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
padding: 20px;
width: 400px;
}
.dialog-header {
font-size: 18px;
font-weight: bold;
text-align: center;
margin-bottom: 20px;
}
.dialog-body {
font-size: 16px;
text-align: center;
margin-bottom: 20px;
}
.dialog-footer {
display: flex;
justify-content: center;
}
.dialog-btn {
border: none;
border-radius: 4px;
color: #fff;
cursor: pointer;
font-size: 16px;
height: 40px;
line-height: 40px;
padding: 0 20px;
transition: background-color 0.3s;
}
.dialog-cancel {
background-color: #999;
margin-right: 10px;
}
.dialog-confirm {
background-color: #409eff;
}
</style>
在上面的代码中,我们定义了自定义弹窗组件 CustomDialog,包含以下 props:
visible:是否显示弹窗
title:弹窗标题
width:弹窗宽度
content:弹窗内容,支持 HTML 标签
confirmText:确定按钮文本
cancelText:取消按钮文本
beforeClose:关闭前的回调函数,返回 false 可以阻止关闭
在组件中,我们使用 ElDialog 组件来实现弹窗,通过 v-html 指令渲染 content 内容,并在 footer slot 中添加确定和取消按钮。
2. 在父组件中使用弹窗组件
<template>
<div>
<button @click="showAlert">alert 弹窗</button>
<button @click="showConfirm">confirm 弹窗</button>
<dialog :visible="alertVisible" :title="alertTitle" :message="alertMessage" @confirm="handleAlertConfirm" />
<dialog :visible="confirmVisible" :title="confirmTitle" :message="confirmMessage" @cancel="handleConfirmCancel" @confirm="handleConfirmConfirm" />
</div>
</template>
<script>
import Dialog from '@/components/Dialog.vue'
export default {
components: {
Dialog
},
data() {
return {
alertVisible: false,
alertTitle: '提示',
alertMessage: '这是一个 alert 弹窗',
confirmVisible: false,
confirmTitle: '提示',
confirmMessage: '这是一个 confirm 弹窗'
}
},
methods: {
showAlert() {
this.alertVisible = true
},
showConfirm() {
this.confirmVisible = true
},
handleAlertConfirm() {
this.alertVisible = false
},
handleConfirmCancel() {
this.confirmVisible = false
},
handleConfirmConfirm() {
this.confirmVisible = false
console.log('点击了确定按钮')
}
}
}
</script>
在父组件中,我们使用 button 元素来触发打开 alert 和 confirm 弹窗事件,然后在组件中使用 Dialog 组件,并传入相应的 props。
在 handleAlertConfirm 和 handleConfirmCancel 方法中,我们通过修改相应的 visible 属性来控制弹窗的显示和隐藏。在 handleConfirmConfirm 方法中,我们可以执行相应的操作,并关闭弹窗。
3. 使用方式
在 Vue 项目中,我们可以在需要使用弹窗的地方引入父组件,然后按照上面的方式使用即可。
<template>
<div>
<!-- 引入父组件 -->
<AlertConfirm />
</div>
</template>
<script>
import AlertConfirm from '@/components/AlertConfirm.vue'
export default {
components: {
AlertConfirm
}
}
</script>
在上面的代码中,我们引入了 AlertConfirm 组件,然后在模板中使用即可。当然,你也可以根据自己的需求来修改组件的样式和功能。