vue+el-element中根据文件名动态创建dialog的方法
背景
在项目中使用对话框的通常做法是把对话框封装成组件,在使用的地方引入,然后添加到template,使用visible.sync控制对话框的显示/隐藏,监听confirm事件处理用户点击确定。如下:
1 <confirm-dialog
2 v-if="confirmDialogVisible"
3 :title="$t(`mineData.tips.deleteDataset`)"
4 :visible.sync="confirmDialogVisible"
5 @confirm="confimHandler"
6 ></confirm-dialog>
在封装的dialog内部也需要在关闭时更新visible,确定时触发confirm事件:
1 methods: {
2 close() {
3 this.$emit("update:visible", false);
4 },
5 confirm() {
6 this.close();
7 this.$emit("confirm");
8 }
9 }
这样的做法不仅仅导致页面初始化时引入所有对话框组件而影响加载速度,更头疼的是页面中引入了很多对话框时,会导致页面很杂乱:需要为每个对话框插入一段html,为每个对话框维护一个单独的visible变量,为每个对话框添加confirm事件监听...
而这些操作大部分是和业务无关的,且这些操作又是极其相似的。
那么,有没有通过js动态创建dialog的方法呢?
1 createDialog("confirm-dialog.vue");
就像上面这样根据文件名即可打开对话框,不用定义visible及添加一堆html和事件回调,甚至不需要先引入对话框组件!
是不是很简单!心动了吧?看下去吧。
实现
1.封装的/utils/dialogControl.js
1 import Vue from 'vue'
2 async function createDialog (fileName, data) {
3 const dialogsContext = require.context(
4 '../components', // 定义查找文件的范围
5 true,
6 /([a-zA-Z\-0-9]+)\.vue$/, // 定义文件名规则
7 'lazy'
8 )
9 // 查找到传入名字的文件并加载该文件
10 let match = dialogsContext.keys().find((key) => key.includes(fileName))
11 if (!match) return
12 let componentContext = await dialogsContext(match)
13 let temp = componentContext.default
14 return new Promise(function (resolve, reject) {
15 // 初始化配置参数
16 let opt = {
17 data
18 }
19 let component = Object.assign({}, temp)
20 let initData = {
21 visible: true
22 }
23 Object.assign(initData, component.data())
24 opt.data && Object.assign(initData, JSON.parse(JSON.stringify(opt.data)))
25 component.data = function () {
26 return initData
27 }
28 // 创建构造器创建实例挂载
29 let DialogC = Vue.extend(component)
30 let dialog = new DialogC()
31 // 关闭事件
32 let _onClose = dialog.$options.methods.onClose
33 dialog.onClose = function () {
34 resolve()
35 dialog.$destroy()
36 _onClose && _onClose.call(dialog)
37 document.body.removeChild(dialog.$el)
38 }
39 // 回调事件
40 let _onCallback = dialog.$options.methods.onCallback
41 dialog.onCallback = function (...arg) {
42 try {
43 _onCallback && _onCallback()
44 resolve(arg)
45 dialog.$destroy()
46 _onClose && _onClose.call(dialog)
47 document.body.removeChild(dialog.$el)
48 } catch (e) {
49 console.log(e)
50 }
51 }
52 dialog.$mount()
53 // 点击关闭按钮时会改变visible
54 dialog.$watch('visible', function (n, o) {
55 dialog === false && dialog.onClose()
56 })
57 document.body.appendChild(dialog.$el)
58 })
59 }
60
61 export { createDialog }
说明:
1.需要指定查找文件的路径及匹配名称的正则表达式,这样能过滤掉一些不需要的文件
2.接收一个fileName参数用于匹配要打开的对话框文件,data参数是传递给对话框的数据,会合并到组件的data中
3.使用visible变量控制对话框的显示/隐藏
4.定义了一个onClose方法用于关闭对话框,对话框中可以使用该方法进行关闭
5.onCallback方法用于向调用对话框的父组件传值,如点击确定按钮时向父组件传值
2.dialog文件定义
如/components/ConfirmDialog.vue,使用visible变量控制显示/隐藏,onClose处理关闭事件,确定按钮的回调是onCallback(和dialogControl.js中的定义一致)。
1 <template>
2 <el-dialog title="提示" :visible.sync="visible" width="30%">
3 <span>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nesciunt quis
4 perspiciatis fugiat molestiae provident accusantium repudiandae fugit
5 minima, eaque, repellat quibusdam iste sed ad? Debitis qui praesentium
6 minus incidunt esse!</span>
7 <span slot="footer" class="dialog-footer">
8 <el-button @click="onClose">取 消</el-button>
9 <el-button type="primary" @click="onCallback(true)">确 定</el-button>
10 </span>
11 </el-dialog>
12 </template>
13
14 <script>
15 export default {
16 data () {
17 return {}
18 },
19 methods: {
20 }}
21 </script>
3.使用
引入dialogControl中的createDialog方法,直接传入文件名称即可打开。
如果有其他的属性,则以键值对的形式放入第二个参数,这些属性会合并到对话框组件的data中,因此对话框组件中可以直接使用这些属性。
createDialog方法得到一个promise对象,其then方法能得到confirm返回的结果。
1 <template>
2 <div>
3 <h1>This is an show page</h1>
4 <el-button type="primary" @click="openDialog">打开</el-button>
5 </div>
6 </template>
7
8 <script>
9 import { createDialog } from "@/utils/dialogControl";
10 export default {
11 methods: {
12 openDialog() {
13 let dialog = createDialog("confirm-dialog.vue");
14 dialog.then((v) => {
15 if (v) {
16 console.info("确定");
17 }
18 });
19 },
20 },
21 };
22 </script>
效果如下:

如果你还在使用文章开始的方式调用对话框,那么赶紧把这个方法用起来吧!
参考:
https://www.freesion.com/article/43311065748/
vue+el-element中根据文件名动态创建dialog的方法的更多相关文章
- odoo 动态创建字段的方法
动态创建字段并非一个常见的的需求,但某些情况下,我们确实又需要动态地创建字段. Odoo 中创建字段的方法有两种,一种是通过python文件class中进行定义,另一种是在界面上手工创建,odoo通过 ...
- Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法
详细说明:Visual c++例子,可不使用常规的对话框资源模板的情况下,动态创建对话框的方法.该方法可以在运行时在内存中直接建立对话框资源,使用起来更为灵活.适用于多个开发项目共享有界面的公用程序模 ...
- python-获取类名和方法名,动态创建类和方法及属性
获取类名和方法名1.在函数外部获取函数名称,用.__name__获取2.在函数内部获取当前函数名称,用sys._getframe().f_code.co_name方法获取3.使用inspect模块动态 ...
- .Net 中的反射(动态创建类型实例) - Part.4
动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...
- .Net 中的反射(动态创建类型实例)
动态创建对象 在前面节中,我们先了解了反射,然后利用反射查看了类型信息,并学习了如何创建自定义特性,并利用反射来遍历它.可以说,前面三节,我们学习的都是反射是什么,在接下来的章节中,我们将学习反射可以 ...
- js中几种动态创建元素并设置文本内容的比较,及性能测试。
内容 1 appendChild (都兼容) 2.insertAdjacentHTML (都兼容) 3.innerHTML (都兼容) 4.createDocumentFragment (都兼容) 动 ...
- 程序员:java中直接或间接创建线程的方法总结
在java开发中,经常会涉及多线程的编码,那么通过直接或间接创建线程的方法有哪些?现整理如下: 1.继承Thread类,重写run()方法 class Worker extends Thread { ...
- 在TFS中通过程序动态创建Bug并感知Bug解决状态
为便于跟踪问题解决情况,预警引擎产生的比较严重的预警日志,需要在TFS中登记Bug,通过TFS的状态流转,利用TFS Bug的Web挂钩功能,动态感知Bug解决状态,从而跟踪预警问题的解决状态, 整体 ...
- [UE4]C++中SpawnActor用法(动态创建Actor)
转自:http://aigo.iteye.com/blog/2270177 C++中创建一个Level并添加的Runtime当中 C++中Spawn一个基于蓝图的Actor https://answe ...
随机推荐
- JavaScript中的多种进制与进制转换
进制介绍 JavaScript 中提供的进制表示方法有四种:十进制.二进制.十六进制.八进制. 对于数值字面量,主要使用不同的前缀来区分: 十进制(Decimal): 取值数字 0-9:不用前缀. 二 ...
- SpringSecurity+Jwt遇到的bug
最近在使用springsecurity整合Jwt的时候,遇到了一Bug,卡住了很久,记录一下. 编写Jwt工具类JwtUtil,编写Jwt认证的核心过滤器JwtAuthenticationFilter ...
- Codeforces 650D - Zip-line(树状数组)
Codeforces 题目传送门 & 洛谷题目传送门 我怕不是个 nt--一开始忽略了"询问独立"这个条件--然后就一直在想有什么办法维护全局 LIS--心态爆炸 首先离散 ...
- Linux—su命令和su -命令的差别(切换登录账号)
1.普通用户切换到root用户,命令su或su - 本人以前一直习惯直接使用root,很少使用su,前几天才发现su与su -命令是有着本质区别的! 大部分Linux发行版的默认账户是普通用户,而更改 ...
- Hadoop运行jar包报错java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1
错误信息: java.lang.Exception: java.lang.ArrayIndexOutOfBoundsException: 1 at org.apache.hadoop.mapre ...
- 数仓:解读 NameNode 的 edits 和 fsimage 文件内容
一.edits 文件 一)文件组成 一个edits文件记录了一次写文件的过程,该过程被分解成多个部分进行记录:(每条记录在hdfs中有一个编号) 每一个部分为: '<RECORD>...& ...
- A Child's History of England.14
At first, Elfrida possessed great influence over the young King, but, as he grew older and came of a ...
- Netty4.x 源码实战系列(一): 深入理解ServerBootstrap 与 Bootstrap (1)
从Java1.4开始, Java引入了non-blocking IO,简称NIO.NIO与传统socket最大的不同就是引入了Channel和多路复用selector的概念.传统的socket是基于s ...
- mysql explain using index condition
Using where:表示优化器需要通过索引回表查询数据:Using index:表示直接访问索引就足够获取到所需要的数据,不需要通过索引回表:Using index condition:在5.6版 ...
- 【Linux】【Commands】trouble shooting命令详解目录
1. 简介 1.1. 最近看到阿里的运维招聘需要熟练掌握以下的命令,我就针对这几个命令做一下总结,有些命令我觉得别人总结的挺好了,我就不赘述了 1.2. 还有一些其他我觉得用得到的命令的用法会在第三部 ...