题目
题目为: vue3中实现一个父页面的弹窗功能,描述显隐和传参的实现逻辑,(效果截图和关键代码截图)
大概的解题思路
- 创建一个弹框组件
弹框.vue
存放于components目录下 - 使用
defineProps
用来获取在父组件中给当前弹框组件传递的值. - 使用
defineEmits
用来将子组件中事件提供给父组件使用.
明确一个弹框组件应该有哪些结构
- header_title: 左上角标题
- main_content: 中间弹框的内容
- footer_operation: 底部操作栏
- 取消.
- 确认.
其中 标题和内容由父组件传递, 而取消和确认事件需要提供给父组件使用.
操作
弹框组件的定义
新建一个弹框组件, 编写基本结构和css样式代码.
基本HTML结构
html
<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样式
CSS
.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
三个方法,分别处理弹框的确认、取消和关闭事件。
js
<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>
父组件调用
html
<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()
用于定义组件可以发出的事件,并返回一个用于触发这些事件的函数。