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.pswp.cn/bicheng/80950.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/80950.shtml
英文地址,請注明出處:http://en.pswp.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…