最近的项目里用上了vue和element-ui。vue这种轻量级渐进式框架的舒适自不必说,但一直困扰着我的,是如何方便又优雅的弹出模态dialog...

对于我这种在jquery出现之前就用document.getElementById敲代码的老顽固来说,我始终不能完全接受把dialog在编码期就写入模板的方式,下面是尤大在知乎某个相关问题的回答节选(全文请看https://www.zhihu.com/question/35820643):

为什么一定要异步插入?
其实以前也有一些用户跟我纠结过这个问题,他们觉得一定要在需要的时候创建这个组件才是符合他们思维的做法。在我看来,这是没有理解『状态驱动的界面』的一种表现。
传统的命令式 (Imperative) 的思维写出来的代码:

$('.open-modal').on('click', function () {
var modal = new Modal()
modal.$appendTo('body')
modal.open()
}) // 在 modal 内部还要处理关闭、销毁自身的逻辑

状态驱动的思维写出来的代码:

this.showModal = true

// 关掉
this.showModal = false

不可否认,尤大所说的状态驱动确实是vue的精髓,但是在实际应用中,dialog往往需要直接在body下才能避免这样那样的问题,就比如本文要说的element-ui的el-dialog问题:如果你在一个el-dialog里,嵌套了另外一个el-dialog,那么弹窗的遮罩层会相互影响,导致用户无法使用(新发布的element-ui 2.0已经解决了嵌套弹窗的问题,文档在这里http://element.eleme.io/#/zh-CN/component/dialog)。

这就要求我们把系统中所有可能出现的dialog,都预先放在vue的根组件中,但显然这是不合理的,根组件无法预知业务模块中将会出现的dialog。dialog应该和alert、messagebox、toast一样,提供方法级别的调用,但不知为何element-ui为后者们提供了全局方法,但对dialog却没有。

本文的目的,就是为了分享一个为dialog提供全局方法的做法。这是我在csdn上看到的一篇文章,确实解决了我的问题,原文在这里:http://blog.csdn.net/zmy_coder/article/details/78042485

原理就是在方法被调用时,在body里create一个div,并且创建一个Vue实例,指定el属性为这个div。

//dialog.js
function makeDialog(option) {
var dom = document.createElement('div');
document.getElementsByTagName('body')[0].appendChild(dom);
let tpl = '\
<el-dialog \
:close-on-click-modal="false" \
:custom-class="customClass" \
:title="title" \
:visible.sync="show" \
:size="size" \
:before-close="handleClose" \
@close="close">\
<dialogContent @close="closeDialog" @confirm="confirmDialog" v-model="dialogData"></dialogContent>\
</el-dialog>';
var vue = new Vue({
el: dom,
data: function () {
return {
title: option.title,
size: option.size || 'small',
show: true,
dialogData: option.data,
};
},
template: tpl,
computed: {
customClass(){
return `el-dialog--width-${option.size || 'auto'}`;
}
},
methods: {
handleClose(done){
if (option.beforeClose) {
option.beforeClose(done);
} else {
done();
}
},
close() {
if (option.close) {
option.close();
}
}, closeDialog(){
this.show = false
},
confirmDialog(result){
this.show = false
option.confirm && option.confirm(result)
}
},
components: {
dialogContent: option.component,
},
});
return vue;
} export default {
open(options){
return makeDialog(options)
}
}

在创建的这个Vue实例里,用到了el-dialog组件,并且具体的内容由外部调用者以component的形式传入,如果该component需要初始数据,需要为该component定义一个value属性,并且在调用open方法时,用options.data传入,并且可以设置在对话框beforeClose、close、confirm时的回调

用法示例:

对话框内容:

<!--SimpleDialogTest.vue-->
<template>
<div class="tutorial">
请输入您的姓名 <input class="form-control" v-model="name"> <button type="button" class="btn btn-primary" @click="submit">确定</button>
<button type="button" class="btn btn-default" @click="cancel">取消</button>
</div>
</template>
<style lang="scss" rel="stylesheet/scss" scoped> </style>
<script type="text/ecmascript-6">
import dialog from '../../assets/js/dialog'
export default{
props: {
value: Object,
},
data(){
return {
name : this.value.name
}
}, methods: {
submit(){
console.log('your name is ' + this.name)
//do something if you like
//... //关闭对话框
this.$emit('close'); //关闭对话框, 并回调调用者的option.confirm方法
// this.$emit('confirm', {
// ...
// });
},
cancel(){
this.$emit('close')
}
}, }
</script>

调用方:

<!---调用方-->
<template>
<button @click="openDialog">弹出对话框</button>
</template>
<script type="text/ecmascript-6">
import dialog from '../assets/js/dialog'
import SimpleDialogTest from 'SimpleDialogTest.vue'
export default{
data(){
return{
}
},
methods:{
openDialog(){
dialog.open({
title: '标题标题',
size:'small', //可选项tiny/small/large/full, 对应el-dialog的size属性
component: SimpleDialogTest,
data: {
name: 'your name',
},
// beforeClose: (done) => {
// //点右上角关闭按钮后触发
// console.log('dialog is closing');
// done()
// },
close: () => {
//关闭后触发
console.log('dialog is closed')
},
confirm: (result) => {
//显式$emit('confirm')时触发
console.log('dialog is confirmed, and dialog result is ', result)
}
})
}
}
}
</script>

关于option的size

el-dialog中size的四个选项tiny/small/large/full在实际应用中是不够的,有时候我们希望能为dialog能自适应内容组件的宽度,也就是说由内容组件来决定宽度,应该怎么做呢?

首先定义一个全局的css:

.el-dialog.el-dialog--width-auto{
width:auto !important;
}

然后在调用dialog.open()的时候,不要指定size属性就行了。

关于el-dialog,我更推荐的用法的更多相关文章

  1. DDGScreenShot--iOS 图片裁剪,切圆角,加边框,你还用cornerRadius,还有更高级的用法

    写在前面 我们肯定做过这样的需求,给一个图片切圆角, 当然我们大多采用简单粗暴的方法 myIcon.layer.cornerRadius = 16.5 myIcon.layer.masksToBoun ...

  2. EL表达式多条件或判断用法

    简单记录一EL表达式的判断用法 <c:if test="${(order.status == '06'&& order.type=='02') || (order.st ...

  3. EL/JSTL-jsp页面更简单的输出方式

    1.EL(Expression Language):表达式语言,用于页面输出 格式:${表达式} EL支持四则运算,关系运算[常用eq来比较字符串或判断相等],逻辑运算 EL访问空间内对象,[类.对象 ...

  4. 设置程序版本等信息(可直接修改pro文件设置,但是更推荐使用rc文件设置)

    Qt版本:5.2.0 在.pro文件中设置版本等信息 VERSION = 1.2.3 QMAKE_TARGET_PRODUCT = 产品名称QMAKE_TARGET_COMPANY = 公司QMAKE ...

  5. fabric 更详尽的用法

    项目发布和运维的工作相当机械,频率还蛮高,导致时间浪费在敲大量重复的命令上. 修复bug什么的,测试,提交版本库(2分钟),ssh到测试环境pull部署(2分钟),rsync到线上机器A,B,C,D, ...

  6. MySql 比Replace Into更适合的用法,外加SqlServer的方式。

    Mysql: INSERT INTO `his_examine_result` (Mid,His_Examine_Mid, His_File_Mid, ResultType, His_Employee ...

  7. 12.VUE - v-bind 详解

    v-bind指令用于给html标签设置属性. <!-- 完整语法 --> <a v-bind:href="url"></a> <!-- 缩 ...

  8. Vim: 强大的g

    来源于:http://vim.wikia.com/wiki/Power_of_g 一般格式: :[range]g/pattern/cmd 对range内所有符合pattern的行执行cmd 常见的一些 ...

  9. create-react-app 核心思路分析

    原文链接:http://axuebin.com/articles/fe-solution/cli/cra.html,转载请联系 Create React App is an officially su ...

随机推荐

  1. Maven生成可以直接运行的jar包的多种方式

    Maven可以使用mvn package指令对项目进行打包,如果使用Java -jar xxx.jar执行运行jar文件,会出现"no main manifest attribute, in ...

  2. 搭建LAMP及wordpress

    author:JevonWei 版权声明:原创作品 安装软件包 [root@danran ~]# yum -y install httpd mariadb-server mariadb php php ...

  3. 深入理解line-height

    什么是行间距? 古时候我们使用印刷机来出来文字.印刷出来的每个字,都位于独立的一个块中. 行间距,即传说中控制两行文字垂直距离的东东.在CSS中,line-height被用来控制行与行之间垂直距离. ...

  4. WPF--鼠标右键菜单中的Command命令实现

    一个功能,在ListView中的ListBoxItem控件上实现右键菜单关闭选项,将该ListBoxItem从ListView中删除. 利用 RoutedCommand类创建Command命令,MSD ...

  5. Vuex 最简单的数量增减实例

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 ...

  6. Git简易参考手册

    如果用过mercury(HG),那么理解Git的运作方式就轻松多了.两者是相同的分布式版本管理工具,只是某些功能有着细微的差别 - Git的管理粒度更加细腻,因此操作上也比HG复杂一点.例如,修改文件 ...

  7. 【Alpha】第七次Daily Scrum Meeting

    GIT 一.今日站立式会议照片        二.会议内容 1.讨论送礼物的方法和对象,使功能更加完善. 2.对于程序还存在的问题提出自己的看法,尽量让功能更加的饱满. 三.燃尽图 四.遇到的困难 能 ...

  8. 个人作业2-英语学习案例app分析

    第一部分 调研, 评测 (软件的bug,功能评测,黑箱测试, 第8章 用户调研, 12 章 软件的用户体验) 下载并使用,描述最简单直观的个人第一次上手体验. ①个人感觉还不错,词典的首页页面挺好看的 ...

  9. Eclipse安装完findbugs插件后,SVN插件不可用有关问题解决

    Eclipse安装完findbugs插件后,SVN插件不可用问题解决: 安装findbugs插件后,SVN插件就消失了.后来从网上查到解决方案:eclipse/configuration目录下的org ...

  10. 201521123114 《Java程序设计》第4周学习总结

    1. 本章学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. 学会了设计一个类时,尽量用private修饰属性,public修饰方法:类名的首字母要大写. ...