题目
题目为: vue3中实现一个父页面的弹窗功能,描述显隐和传参的实现逻辑,(效果截图和关键代码截图)
大概的解题思路
- 创建一个弹框组件
弹框.vue
存放于components目录下 - 使用
defineProps
用来获取在父组件中给当前弹框组件传递的值. - 使用
defineEmits
用来将子组件中事件提供给父组件使用.
明确一个弹框组件应该有哪些结构
- header_title: 左上角标题
- main_content: 中间弹框的内容
- footer_operation: 底部操作栏
- 取消.
- 确认.
其中 标题和内容由父组件传递, 而取消和确认事件需要提供给父组件使用.
操作
弹框组件的定义
新建一个弹框组件, 编写基本结构和css样式代码.
基本HTML结构
代码语言:javascript复制<template>
<div v-if="visible" class="dialog-overlay" @click="cancel">
<div class="dialog">
<div class="dialog-header">
<span class="dialog-title">{{ title }}</span>
<button class="dialog-close" @click="cancel">×</button>
</div>
<div class="dialog-body">
<p>{{ content }}</p>
</div>
<div class="dialog-footer">
<button @click="cancel">取消</button>
<button @click="confirm">确定</button>
</div>
</div>
</div>
</template>
CSS样式
代码语言:javascript复制.dialog-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
color: rgb(0, 0, 0);
display: flex;
justify-content: center;
align-items: center;
}
.dialog {
background: white;
padding: 20px;
border-radius: 5px;
width: 400px;
max-width: 90%;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.dialog-title {
font-size: 18px;
font-weight: bold;
}
.dialog-close {
background: none;
color: red;
border: none;
font-size: 20px;
cursor: pointer;
}
.dialog-body {
margin-bottom: 20px;
}
.dialog-footer {
text-align: right;
}
.dialog-footer button {
margin-right: 10px;
}
js 部分
变量
其中 visible 用来控制弹框的显示, title 为标题, content 为弹框内容. required 表示 visible为必需传递的值, 然后default 是当父组件不传递的时候, 就采用default默认值.
事件
- 定义了
handleConfirm
、handleCancel
和handleClose
三个方法,分别处理弹框的确认、取消和关闭事件。
<script setup>
const props = defineProps({
visible: {
type: Boolean,
required: true,
},
title: {
type: String,
default: '弹框标题'
},
content: {
type: String,
default: '这是默认的弹框的内容'
}
});
const emit = defineEmits(['confirm', 'cancel', 'close']);
const close = () => {
emit('close');
};
const confirm = () => {
emit('confirm');
close();
};
const cancel = () => {
emit('cancel');
close();
};
</script>
父组件调用
代码语言:javascript复制<template>
<div>
<button @click="openDialog">打开弹框</button>
<MyDialog :visible.sync="dialogVisible" :title="title" :content="dialogContent" @confirm="handleConfirm"
@cancel="handleCancel" @close="handleClose">
</MyDialog>
</div>
</template>
<script setup>
import { ref } from 'vue';
import MyDialog from '@/components/MyDialog.vue';
const dialogVisible = ref(false);
const dialogContent = ref('父组件传递过来的弹框内容');
const title = ref('父组件传递过来的弹框标题');
const openDialog = () => {
dialogVisible.value = true;
};
const closeDialog = () => {
dialogVisible.value = false;
};
const handleConfirm = () => {
console.log('弹框确认事件');
closeDialog();
};
const handleCancel = () => {
console.log('弹框取消事件');
closeDialog();
};
const handleClose = () => {
console.log('弹框关闭事件');
closeDialog();
};
</script>
说明:
- 在父组件中:
- 用户点击 “打开弹框” 按钮时,触发
openDialog
方法。 openDialog
方法将dialogVisible
的值设置为true
。dialogVisible
的变化通过 Vue 的响应式系统传递给MyDialog
组件,使其显示。
- 用户点击 “打开弹框” 按钮时,触发
- 在子组件 (
MyDialog
) 中:visible
属性的值从父组件传递过来,并通过v-if
控制弹框的显示与隐藏。- 用户点击弹框内的 “确定” 按钮时,触发
confirm
方法。 confirm
方法通过emit
触发confirm
事件,并调用close
方法。close
方法触发close
事件。
- 在父组件中:
- 监听
MyDialog
组件的confirm
、cancel
和close
事件。 - 当
confirm
事件被触发时,父组件执行handleConfirm
方法,记录日志并关闭弹框(即将dialogVisible
设置为false
)。 - 当
cancel
或close
事件被触发时,父组件分别执行handleCancel
或handleClose
方法,记录日志并关闭弹框。
- 监听
效果
扩展学习
-
defineProps()
用于定义组件的属性,并返回一个包含这些属性的对象。 -
defineEmits()
用于定义组件可以发出的事件,并返回一个用于触发这些事件的函数。