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 ...
随机推荐
- java 适配器模式实现代码
目录 1.适配器模式 1.1.类适配器 1.2.对象适配器 2.适配器模式实例 1.适配器模式 适配器模式可以分为类适配器和对象适配器. 1.1.类适配器 //目标接口 interface Targe ...
- [Noip 2012]同余方程(线性同余方程)
我们先放题面-- RT就是求一个线性同余方程ax≡1(mod b)的最小正整数解 我们可以将这个同于方程转换成这个方程比较好理解 ax=1+bn(n为整数 我们再进行一个移项变为ax-bn=1 我们设 ...
- [NOIP2017 提高组] 列队
考虑我们需要维护的是这样一个东西. 即可能变化的只有每一行前\(m - 1\)个,和最后一列. 我们考虑对每一行开一个权值线段树,记录原本序列的第\(x\)个是否被一出,且用一个\(vector\)记 ...
- [Codeforces Global Round 14]
打挺差的. 不过\(C,D\)一眼秒了,大概是对这几个月努力的一个结果? \(B\)玄学错误挂了两发. 脑子痛然后打到一半就去睡觉了. -------------------------------- ...
- Codeforces 840E - In a Trap(树分块+trie)
Codeforces 题面传送门 & 洛谷题面传送门 一道非常精彩,同时也很经典的题目.和这场的 C 一样经典 首先看到这个数据范围先猜正解复杂度:\(n\) 级别大于 \(q\),所以大概是 ...
- C++ and OO Num. Comp. Sci. Eng. - Part 4.
命名空间与文件(Namespaces and Files) 在 C++ 中,命名空间为包含相关声明与定义的逻辑单元. 将一个大程序分割为不同部分并且将其储存在不同的文件中可以实现模块化编程. 未命名的 ...
- 金蝶EAS——我的EAS报销流程怎么能让另一个人看到呢?即如何设置流程传阅功能?设置“代理报销”
代理的话只能看到被代理人能看到的流程.设置"代理报销":应用--财务会计--费用管理--代理报销 选择报销人公司--"他人代理我报销"--选择报销人(zhaof ...
- 45-Letter Combinations of a Phone Number
Letter Combinations of a Phone Number My Submissions QuestionEditorial Solution Total Accepted: 7855 ...
- 一款真正可以拿的出手的本土嵌入式RTOS-SylixOS
由 winniewei 提交于 周四, 12/20/2018 作者:张国斌 在参加工信部人才交流中心和南京浦口区开发区管委会联合举办的第三届集成电路产业紧缺人才创新发展高级研修班暨产业促进交流会期间, ...
- day02 web主流框架
day02 web主流框架 今日内容概要 手写简易版本web框架 借助于wsgiref模块 动静态网页 jinja2模板语法 前端.web框架.数据库三种结合 Python主流web框架 django ...