news 2026/9/3 8:27:29

dialog封装

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
dialog封装

通用封装弹窗 / 自定义组件模板,可套用

// 子组件<template><el-dialog v-model="innerFlag"title="弹窗">// 业务内容<template #footer><spanclass=""><el-button @click="state.peopleDialogShow = false">取消</el-button><el-button type="primary"@click="confirm">确定</el-button></span></template></el-dialog></template><script setup>import{computed}from'vue'// 1. 定义接收的开关参数constprops=defineProps(['show'])// 2. 定义更新事件 + 业务事件constemit=defineEmits(['update:show','confirmSelect'])// 封装双向绑定constinnerFlag=computed({get(){returnprops.show},set(val){emit('update:show',val)}})// 业务操作,抛出数据constconfirm=()=>{emit('confirmSelect','选中的数据')}</script>// 父组件<CustomDialog v-model:show="isDialogShow"@confirmSelect="getData"/><script setup>constisDialogShow=ref(false)constgetData=(res)=>{console.log('子组件传回数据',res)isDialogShow.value=false}</script>

业务示例:

<template><el-dialogv-model="innerVisible"title="组件Library"v-if="innerVisible"width="90%"style="margin-top:4%"><divclass="comBox"><divclass="xxBox"@click="selectComp('msg')"><XxCom></XxCom></div><divclass="rwBox"@click="selectComp('task')"><RwCom></RwCom></div><divclass="chartBox"@click="selectComp('chart')"><BarChartref="barChartsChild"></BarChart></div></div></el-dialog></template><scriptsetup>import{ref,onMounted,reactive,computed,}from'vue'importXxComfrom'@/components/text/xx.vue'importRwComfrom'@/components/text/rw.vue'importBarChartfrom'@/components/chart/barChart.vue'constemit=defineEmits(['select','update:comDialogShow'])constprops=defineProps(['comDialogShow'])constinnerVisible=computed({get(){returnprops.comDialogShow},//父组件传进来的弹窗显示状态set(val){emit('update:comDialogShow',val)}//通知父组件更新变量})// 自定义业务事件 把用户选中的组件标识 传给父页面constselectComp=(key)=>{emit('select',key)}onMounted(()=>{})</script><stylelang="scss"scoped>//dialog 相关样式 .comBox{display:flex;flex-wrap:wrap;gap:12px;/* 模块间距,按需调整 */width:100%;height:100%;overflow:auto;.xxBox, .rwBox, .chartBox, .zbBox{width:24.4%;height:36%;background:#f5f7fa;border-radius:8px;padding:12px;overflow-y:auto;/* 内容超出时滚动 */}}</style>

主页面引入

<template><ComponentLibDialogv-model:comDialogShow="state.dialogVisible"@select="selectCompHandle"/></template><scriptsetup>conststate=reactive({dialogVisible:false,})// 自定义事件;弹窗选中组件,赋值给对应模块constselectCompHandle=(compKey)=>{// 给当前操作模块赋值moduleData[activeModuleId].key=compKey// 关闭弹窗state.dialogVisible=false}</script>
详解 v-model:visible 和 @select 分别是什么、为什么这么写

Vue3 组件自定义双向绑定规范:

v-model:xxx="变量" 等价于 :xxx="变量" @update:xxx="新值 => 变量 = 新值"
  1. v-model:comDialogShow=“dialogVisible” —— Vue3 多参数 v-model 语法
    规则:绑定参数名 xxx,更新事件必须固定叫 update:xxx,这是 Vue 语法约定,不能随便改事件名。
// 弹窗组件里定义了:constemit=defineEmits(['select','update:comDialogShow'])constprops=defineProps(['comDialogShow'])constinnerVisible=computed({get(){returnprops.comDialogShow},//父组件传进来的弹窗显示状态set(val){emit('update:comDialogShow',val)}//通知父组件更新变量})// 父组件对应写法,两种写法完全等价//写法1. 简写(推荐)<ComponentLibDialog v-model:comDialogShow="dialogVisible"/>//写法2. 完整展开写法,更好理解底层<ComponentLibDialog:comDialogShow="dialogVisible"@update:comDialogShow="val => dialogVisible = val"/>//能不能换名字?完全可以,举例子//比如不想用 visible,改用 open://1.子组件改 props、emit 名称:constprops=defineProps(['open'])constemit=defineEmits(['update:open'])constinnerOpen=computed({get(){returnprops.open},set(val){emit('update:open',val)}})//2.父组件同步改成:<ComponentLibDialog v-model:open="dialogVisible"/>
  1. @select=“selectCompHandle” —— 自定义业务事件

子组件触发: emit(‘select’, 参数):第一个参数是事件名,后面是要传给父页面的数据

// 弹窗需要把 用户选中的组件标识(msg/task/chart)传给父页面,所以自定义事件 select// 选中组件时抛出keyconstselectComp=(key)=>{emit('select',key)}

父组件接收: @select=“selectCompHandle”

constselectCompHandle=(compKey)=>{if(!activeModuleId)return// 给当前操作模块赋值组件moduleData[activeModuleId].key=compKey// 关闭弹窗state.comDialogShow=false}

事件名可以随便自定义,没有强制约束
比如你想叫 chooseComponent、pick 都没问题:
子组件:emit(‘chooseComponent’, compKey)
父组件:@chooseComponent=“handleSelectComp”

举个对比示例,换一套名字演示。功能完全不变,只是参数和事件名换了。

//子组件constprops=defineProps(['open'])constemit=defineEmits(['update:open','pickComponent'])constinnerOpen=computed({get(){returnprops.open},set(val){emit('update:open',val)}})consthandleSelect=(key)=>{emit('pickComponent',key)innerOpen.value=false}//父组件<ComponentSelectDialog v-model:open="dialogVisible"@pickComponent="handleSelectComp"/>

总结:两类事件的区别

类型语法规则作用命名约束
v-model:xxx 双向绑定事件固定 update:xxx同步开关类状态(弹窗显隐、开关、输入框值)更新事件名不能自定义,必须 update:xxx
自定义业务事件 @xxx事件名完全自定义传递业务数据(选中项、提交、删除、点击)随便起名,见名知意即可

使用场景:
什么时候用 v-model:xxx,什么时候用自定义事件?
1.控制开关、输入值、显隐这类双向同步状态 → 用 v-model:xxx
2.点击选择、提交、删除、获取业务数据这类单向回调传参 → 自定义事件 @xxx

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 8:27:23

Linux:信号量,生产者消费者模型和日志实现

目录 1.什么是信号量 2.基于环形队列的生产者消费者模型 3.日志的实现 1.什么是信号量 信号量的本质是一把计数器&#xff0c;描述资源的数量。申请信号量的本质是用来预定资源的&#xff0c;比如买电影票。因为信号量也是共享资源&#xff0c;同时只能一个线程访问&#…

作者头像 李华
网站建设 2026/9/3 8:26:29

架构图 Agent 实战:从环境搭建到批量生成的可落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 8:21:56

C++类和对象(一)—— 类的定义、封装、对象与this指针

文章目录1. 类的基础知识1.1 类的定义1.1.1class和struct的对比1.1.2 类内定义函数是inline1.1.3 为什么类内函数默认inline&#xff1f;1.2 访问限定符1.2.1 为什么要有访问限定符&#xff1f;1.2.1.1 为什么要有封装性&#xff1f;1.2.2 访问限定符作用的范围1.2.3 访问限定符…

作者头像 李华
网站建设 2026/9/3 8:21:34

基于OpenCV的RGBD视觉里程计实现:从原理到SLAM应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 8:21:08

HOMIE Gen2与人类经验Scaling Law:从概念到落地验证指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 8:19:55

校园二手交易系统:SpringBoot+Vue企业级毕设实战

简介&#xff1a;这是一套面向计算机类专业本科生的高分毕业设计级校园二手交易平台实战项目&#xff0c;适用于毕业设计、课程设计及期末大作业场景&#xff0c;帮助学生快速掌握前后端分离开发全流程。资源包含1151个文件&#xff0c;涵盖443张界面截图与图标资源&#xff08…

作者头像 李华