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 ...
随机推荐
- SQLite3 约束和简单命令
安装sqlite3,配置环境变量. 1.打开数据库 sqlite3.exe db_name.db 2.常用命令 .tables 查看所有表 .headers on 设置显示表头 .schema tab ...
- window10快捷键 + 浏览器常用通用快捷键
一.window10快捷键 1.win+tab 缩小版的显示出桌面打开的所有窗口,然后再结合上下左右键加enter选择想要的窗口: 如果不想选择或者保留原有显示窗口,再按win+tab 或者 ...
- 19.Happy Number-Leetcode
Write an algorithm to determine if a number is "happy". A happy number is a number defined ...
- JVM2 类加载子系统
目录 类加载子系统 类加载器子系统 类加载器ClassLoader角色 类加载的过程 案例 加载Loading 连接Linking 初始化Intialization clinit() 类的加载器 虚拟 ...
- 生产调优3 HDFS-多目录配置
目录 HDFS-多目录配置 NameNode多目录配置 1.修改hdfs-site.xml 2.格式化NameNode DataNode多目录配置(重要) 1.修改hdfs-site.xml 2.测试 ...
- 网口程序udp
# -*- coding: utf-8 -*- """ Created on Thu Nov 12 15:02:53 2020 @author: Administrato ...
- 100个Shell脚本——【脚本9】统计ip
[脚本9]统计ip 有一个日志文件,日志片段:如下: 112.111.12.248 – [25/Sep/2013:16:08:31 +0800]formula-x.haotui.com "/ ...
- Oracle中的job(定时任务)
oracle中的job(定时任务)由dbms_job包下的函数实现.关于job的理论知识可参考https://blog.csdn.net/apextrace/article/details/77675 ...
- ORACLE DBMS_ROWID包详解
这个包在11gR2中有11个函数或存储: 1. 根据给定参数返回一个rowid --根据给定参数返回一个rowid FUNCTION rowid_create(rowid_type IN NUMBER ...
- 编译安装haproxy2.0
先解决lua环境,(因为centos自带的版本不符合haproxy要求的最低版本(5.3)先安装Lua依赖的包 [root@slave-master lua-5.3.5]# yum install ...