Vue2 elementUI 二次封装命令式表单弹框组件

需求:封装一个表单弹框组件,弹框和表单是两个组件,表单组件以插槽的形式动态传入弹框组件中。

外部组件使用的方式如下:

直接上代码:

MyDialog.vue 弹框组件

<template><el-dialog:title=title:visible.sync="dialogVisible":close-on-click-modal="false"width="40%"><slot name="content"></slot><span slot="footer" class="dialog-footer"><el-button size="mini" @click="handleCancelClick">取 消</el-button><el-button size="mini" type="primary" @click="handleOkClick">确 定</el-button></span></el-dialog>
</template><script>
export default {name: "MyDialog",props: {title: {type: String},message: {type: String},icon: {type: String,default: "info"},handleCancel: {type: Function},handleOk: {type: Function}},data() {return {dialogVisible: true,}},methods: {handleCancelClick() {this.dialogVisible = false;this.handleCancel();},handleOkClick() {this.dialogVisible = false;this.handleOk();},handleTestClick() {this.$emit('test-click')},}
}
</script><style scoped>/deep/.el-dialog__body {padding: 15px 20px;}/deep/ .el-dialog__header {padding: 2px 10px 2px;background-color: #1E2C3D;color: white;}/deep/ .el-dialog__title {color: white;font-size: 13px;font-family: 微软雅黑,serif;}/deep/ .el-dialog__headerbtn {top: 6px;}/deep/ .el-dialog__headerbtn .el-dialog__close {color: #fff;}</style>

 MyDialog.js 

import Vue from 'vue';
import MyDialog from "@/components/dialog4/MyDialog.vue";
import EventBus from "@/lib/event-bus";/*** 弹框组件的构造器* @param ctxCpm* @param dlgProps* @param onOkClick* @param onCancelClick* @returns {ExtendedVue<Vue, unknown, unknown, unknown, Record<never, any>, {}, ComponentOptionsMixin, ComponentOptionsMixin>|VNode}*/
function getDialogConstructor(ctxCpm, dlgProps, onOkClick, onCancelClick) {return Vue.extend({render(h) {return h(MyDialog, {props: {...dlgProps,handleOk: onOkClick,handleCancel: onCancelClick}},[h(ctxCpm, {slot: 'content',ref: 'myform',},)])}})
}// 暴露此函数供外部组件调用
/*** * @param ctxCpm     表单组件 * @param dlgProps   弹框组件的配置项props* @param onOkClick  确认按钮点击事件回调函数* @param onCancelClick 取消按钮点击事件回调函数* @returns {(function(): void)|*}  弹窗关闭后的回调函数*/
export const useDialog = (ctxCpm, dlgProps, onOkClick, onCancelClick) => {let DialogConstructor = getDialogConstructor(ctxCpm, dlgProps, () => {EventBus.$emit('form-submit', {callback: (formData) => {onOkClick(formData);}});}, onCancelClick);const dlg = new DialogConstructor();const dlgInstance = dlg.$mount();document.body.appendChild(dlgInstance.$el);return () => {dlgInstance.$el.remove();dlgInstance.$destroy();EventBus.$off("form-submit");		// 移除表单提交事件监听}
}

UserForm.vue 表单组件

<template><el-form><el-form-item label="用户名"><el-input v-model="form.name"></el-input></el-form-item><el-form-item label="年龄"><el-input v-model="form.age"></el-input></el-form-item><el-form-item label="住址"><el-input v-model="form.address"></el-input></el-form-item></el-form>
</template><script>
import EventBus from "@/lib/event-bus";export default {name: "UserForm",props: {dlgProps: Object},data() {return {form: {name: '',age: 0,address: ''}}},methods: {takeFormData() {return {...this.form}}},created() {// 监听表单提交(确认按钮点击)EventBus.$on('form-submit', (p) => {p.callback(this.takeFormData());});}
}
</script><style scoped></style>

MyDialogTest.vue 组件中调用

<template><div><el-button @click="handleClick">点我弹出用户组件弹框</el-button></div>
</template><script>
import {useDialog} from "@/components/dialog4/MyDialog";
import UserForm from "@/components/dialog4/UserForm";export default {name: "MyDialogTest",methods: {handleClick() {const close = useDialog(UserForm, {title: "新增用户表单", message: "是否确定?", icon: "warn"}, (params) => {console.log("Test.....", params);close();}, () => {console.log("取消按钮被点击");close();})}}
}
</script><style scoped></style>

效果如下:

优化1: 

以上的写法中,是采用EventBus 事件总线的方式来获取表单提交的数据,也就是点击确认后提交表单,在onOkClick 处理函数中获取表单数据。后面想了想,可以再精简一点。

MyDialog.js

import Vue from 'vue';
import MyDialog from "@/components/dialog5/MyDialog.vue";function getDialogConstructor(ctxCpm, dlgProps, onOkClick, onCancelClick) {return Vue.extend({render(h) {return h(MyDialog, {props: {...dlgProps,handleOk: onOkClick,handleCancel: onCancelClick}},[h(ctxCpm, {slot: 'content',ref: 'myform',props: {fdata: dlgProps.fdata}},)])}})
}export const useDialog = (ctxCpm, dlgProps, onOkClick, onCancelClick) => {let DialogConstructor = getDialogConstructor(ctxCpm, dlgProps, onOkClick, onCancelClick);const dlg = new DialogConstructor();const dlgInstance = dlg.$mount();document.body.appendChild(dlgInstance.$el);return () => {dlgInstance.$el.remove();dlgInstance.$destroy();}
}

这个文件的调整是,在h函数渲染表单组件ctxCpm时,通过props传入一个fdata。把事件总线的代码删了。

那么在表单组件中,就顶一个props fdata来接收。修改如下:

TestForm.vue

<template><el-form><el-form-item label="姓名"><el-input v-model="fdata.name"></el-input></el-form-item><el-form-item label="年龄"><el-input v-model="fdata.age"></el-input></el-form-item></el-form>
</template><script>
export default {name: "TestForm",props: ["fdata"],
}
</script><style scoped></style>

在TestForm.vue 组件中只需要定义一个props来接收即可。

然而,这样修改后,在外部组件中要调用 useDIalog 这个就需要传参数了。

MyDialogTest.vue

<template><div><el-button @click="handleClick">点我弹出弹框</el-button></div>
</template><script>
import TestForm from "@/components/dialog5/TestForm";
import {useDialog} from "@/components/dialog5/MyDialog"
export default {name: "MyDialogTest5",data() {return {fdata: {}}},methods: {handleClick() {const close = useDialog(TestForm, {fdata: this.fdata}, () => {console.log({...this.fdata})close();}, () => {});}}
}
</script><style scoped></style>

----------------------------------------------------------分隔线----------------------------------------------------------

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React Hooks:从“这什么鬼“到“真香“的奇幻之旅

写在前面:一个让React老手都拍案叫绝的魔法 “等等,函数组件怎么能有状态?!” —— 这是2018年我第一次听说React Hooks时的反应。当时我正在用class组件写一个复杂的表单,生命周期方法乱得像一碗意大利面。直到我看到了这段代码: function Counter() {const [count, s…

论文阅读笔记——双流网络

双流网络论文 视频相比图像包含更多信息&#xff1a;运动信息、时序信息、背景信息等等。 原先处理视频的方法&#xff1a; CNN LSTM&#xff1a;CNN 抽取关键特征&#xff0c;LSTM 做时序逻辑&#xff1b;抽取视频中关键 K 帧输入 CNN 得到图片特征&#xff0c;再输入 LSTM&…

SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

右值引用的学习

传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现在开始我们之前学习的引用就叫做左值引用。无论左值引用还是右值引用&#xff0c;都是给对象取别名。 左值引用和右值引用 在讲之前&#xff0c;我们先来看一下什么是左值和右值…

PHP黑白胶卷底片图转彩图功能 V2025.05.15

关于底片转彩图 传统照片底片是摄影过程中生成的反色图像&#xff0c;为了欣赏照片&#xff0c;需要通过冲印过程将底片转化为正像。而随着数字技术的发展&#xff0c;我们现在可以使用数字工具不仅将底片转为正像&#xff0c;还可以添加色彩&#xff0c;重现照片原本的色彩效…

【Three.js基础学习】36.particles-morphing-shader

前言 通过着色器如何实现粒子之间动态切换 一、代码 script.js import * as THREE from three import { OrbitControls } from three/addons/controls/OrbitControls.js import { GLTFLoader } from three/addons/loaders/GLTFLoader.js import { DRACOLoader } from three/a…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】附录-D. 扩展插件列表(PostGIS/PostgREST等)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 附录D. PostgreSQL扩展插件速查表一、插件分类速查表二、核心插件详解三、安装与配置指南四、应用场景模板五、版本兼容性说明六、维护与优化建议七、官方资源与工具八、附录…

【Linux】冯诺依曼体系结构和操作系统的理解

目录 冯诺依曼体系结构一个例子来深入理解 初识操作系统操作系统的作用设计操作系统的目的操作系统之上和之下分别有啥 管理的精髓&#xff0c;先描述&#xff0c;再组织 冯诺依曼体系结构 我们知道&#xff0c;计算机这个东西发明出来就是帮助人们快速解决问题的。那如果我们想…

kotlin @JvmStatic注解的作用和使用场景

1. JvmStatic 的作用 JvmStatic 是 Kotlin 提供的一个注解&#xff0c;用于在 JVM 上将伴生对象&#xff08;companion object&#xff09;中的方法或属性暴露为 Java 静态方法或字段。 作用对象&#xff1a;只能用在 companion object 中的函数或属性。效果&#xff1a; 在 …

Redis实现-优惠卷秒杀(基础版本)

(一)全局唯一ID 一、全局ID生成器 可以看到在优惠卷订单表中的主键id并没有设置Auto increment自增长 假如未来订单量达到数亿单&#xff0c;单表无法保存如此多数据&#xff0c;就需要对其进行分表存储(分布式)。假如每张表都采用自增长&#xff0c;各自从1开始自增&#xf…

c++STL——哈希表封装:实现高效unordered_map与unordered_set

文章目录 用哈希表封装unordered_map和unordered_set改进底层框架迭代器实现实现思路迭代器框架迭代器重载operator哈希表中获取迭代器位置 哈希表的默认成员函数修改后的哈希表的代码封装至上层容器 用哈希表封装unordered_map和unordered_set 在前面我们已经学过如何实现哈希…

虹科应用 | 探索PCAN卡与医疗机器人的革命性结合

随着医疗技术的不断进步&#xff0c;医疗机器人在提高手术精度、减少感染风险以及提升患者护理质量方面发挥着越来越重要的作用。医疗机器人的精确操作依赖于稳定且高效的数据通信系统&#xff0c;虹科提供的PCAN四通道mini PCIe转CAN FD卡&#xff0c;正是为了满足这一需求而设…

Yolov8的详解与实战-深度学习目标检测

Yolov8的详解与实战- 文章目录 摘要 模型详解 C2F模块 Loss head部分 模型实战 训练COCO数据集 下载数据集 COCO转yolo格式数据集&#xff08;适用V4&#xff0c;V5&#xff0c;V6&#xff0c;V7&#xff0c;V8&#xff09; 配置yolov8环境 训练 测试 训练自定义数据集 Labelme…

scons user 3.1.2

前言 感谢您抽出时间阅读有关 SCons 的内容。SCons 是一款下一代软件构建工具&#xff0c;或者称为 make 工具&#xff0c;即一种用于构建软件&#xff08;或其他文件&#xff09;并在底层输入文件发生更改时使已构建的软件保持最新状态的软件实用程序。 SCons 最显著的特点是…

Java的多线程笔记

创建一个线程的方法有多种&#xff0c;比如可以继承Thread类或者实现Runnable接口&#xff0c;结论是实现Runnable接口比前者更加优越。 二者代码对比 Java 不支持多继承&#xff0c;如果你继承了 Thread 类&#xff0c;就不能再继承其他类&#xff0c;实现 Runnable 接口后&am…

PDF Base64格式字符串转换为PDF文件临时文件

需求描述&#xff1a; 在对接电子病历系统与河北CA&#xff0c;进行免密文件签章的时候&#xff0c;两者系统入参不同&#xff0c;前者是pdf文件&#xff0c;base64格式&#xff1b;后者要求File类型的PDF文件。 在业务中间层开发时&#xff0c;则需要接收EMR侧提供的base64格式…

代码随想录训练营第二十三天| 572.另一颗树的子树 104.二叉树的最大深度 559.N叉树的最大深度 111.二叉树的最小深度

572.另一颗树的子树&#xff1a; 状态&#xff1a;已做出 思路&#xff1a; 这道题目当时第一时间不是想到利用100.相同的树思路来解决&#xff0c;而是先想到了使用kmp&#xff0c;不过这个题目官方题解确实是有kmp解法的&#xff0c;我使用的暴力解法&#xff0c;kmp的大致思…

【RabbitMq C++】消息队列组件

RabbitMq 消息队列组件 1. RabbitMq介绍2. 安装RabbitMQ3. 安装 RabbitMQ 的 C客户端库4. AMQP-CPP 库的简单使用4.1 使用4.1.1 TCP 模式4.1.2 扩展模式 4.2 常用类与接口介绍4.2.1 Channel4.3.2 ev 5. RabbitMQ样例编写5.1 发布消息5.2 订阅消息 1. RabbitMq介绍 RabbitMq - …

鸿蒙NEXT开发动画案例8

1.创建空白项目 2.Page文件夹下面新建Spin.ets文件&#xff0c;代码如下&#xff1a; /*** SpinKit动画组件 (重构版)* author: CSDN-鸿蒙布道师* since: 2025/05/14*/interface AnimationGroup {indexes: number[];delay: number; }ComponentV2 export struct SpinEight {Re…

MySQL全局优化

目录 1 硬件层面优化 1.1 CPU优化 1.2 内存优化 1.3 存储优化 1.4 网络优化 2 系统配置优化 2.1 操作系统配置 2.2 MySQL服务配置 3 库表结构优化 4 SQL及索引优化 mysql可以从四个层面考虑优化&#xff0c;分别是 硬件系统配置库表结构SQL及索引 从成本和优化效果来看&#xf…