我本没有想着说要封装一个弹窗组件,但有同行的朋友在问我,而且弹窗组件也确实在项目开发中用的比较多。思前想后,又本着样式统一且修改起来方便的原则,还是再为大家分享一个我所封装的弹窗组件吧。

其实,并不是所有封装组件的方式都是一成不变的,你可以采用函数式组件这种能提高性能的方式,也可以使用带有状态和生命周期的普通组件的封装方式。但像dialog这种包含很多点击事件如确定或提交事件、取消或重置事件、右上角那个小叉叉的关闭事件等,又有可能包含嵌套其他组件如表格组件、表单组件、树形组件、穿梭框组件等的公共组件,其成分略微复杂,功能不太单一,你若要采用函数式组件的方式来封装也不是不可以,只是可能xue微要麻烦一些,我自己建议是不采用这种封装方式,就采用普通的封装方式就好。

至于普通组件的封装方式,我想大家平时在开发的过程中对所接触的普通组件即带有状态和生命周期,也能快乐地使用this关键词的组件已经是非常熟悉了,所以这种封装方式我就不会再做过多的介绍了。以下是具体的实现过程。

照例还是想来张效果图:



1、所封装的弹窗组件dialog.vue

<template>
<el-dialog
top="20vh"
class="el-dialog-cus"
v-bind="{...$attrs, ...{title, width, center}}"
:visible="visible"
:before-close="beClose"
append-to-body
>
<slot></slot>
<div slot="footer">
<el-button @click="cancel" plain>{{btnTxt[0]}}</el-button>
<el-button @click="confirm" type="primary" v-if="btnTxt[1]">{{btnTxt[1]}}</el-button>
</div>
</el-dialog>
</template> <script>
export default {
inheritAttrs: false,
props: {
title: {
type: String,
default: "提示",
},
width: {
type: String,
default: "420px",
},
center: {
type: Boolean,
default: true,
},
autoClose: {
type: Boolean,
default: true,
},
beforeClose: {
type: Function,
default: () => {}
},
btnTxt: {
type: Array,
default: () => ["取消", "确定"],
},
},
data() {
return {
visible: false,
};
},
methods: {
open(ok) {
this.ok = ok;
this.visible = true;
},
cancel() {
this.visible = false;
},
confirm() {
let cancel = () => this.cancel();
this.ok(cancel);
this.autoClose && cancel();
},
beClose(done) {
done();
this.beforeClose();
this.cancel();
},
},
};
</script> <style lang="scss">
.el-dialog-cus {
.el-dialog {
padding: 8px;
}
.el-dialog__title {
font-weight: bold;
}
.el-dialog__header {
padding: 20px 0 12px;
}
.el-dialog__headerbtn {
top: 8px;
right: 8px;
}
.el-dialog--center .el-dialog__body {
padding: 0 24px;
text-align: center;
}
.el-dialog__footer {
padding: 20px;
.el-button {
padding: 8px 20px;
& + .el-button {
margin-left: 40px;
}
}
}
}
</style>

对于以上的一些代码,我需要做一些特别的说明:

open(ok) {
this.ok = ok;
this.visible = true;
}

这段代码是弹出弹窗的方法,为的是在使用弹窗组件时,我们只需点击一个按钮并使用ref来获取弹窗组件的这个方法即可打开弹窗,剩下的关闭弹窗的操作就交给弹窗的确定或取消按钮来完成即可,我们不用再额外的写关闭弹窗的方法并将关闭弹窗的props参数传给弹窗组件。另外,在打开弹窗的方法中我还保存了一个ok事件,这个ok事件是用于在点击了弹窗组件的确定或提交按钮后所触发的回调方法,比如我们点击了弹窗的提交按钮,我们需要调一个接口来完成数据的存储或修改,那么这个ok事件就是为它实现的,毕竟弹窗组件充当的只是一个我们用于处理业务逻辑的中间桥梁。

confirm() {
let cancel = () => this.cancel();
this.ok(cancel);
this.autoClose && cancel();
}

这段代码是在点击弹窗的确定或提交按钮时触发的,但为什么要给一个之前保存的ok回调函数传一个关闭的方法参数呢,这是因为有时我们在点击了确定或提交的按钮后并不想立即关闭这个弹窗,而是想在几秒钟的倒计时后再关闭这个弹窗并跳转到其他页面,亦或是在A弹窗的基础上又弹出另外一个B弹窗,在B弹窗的基础上又弹出一个C弹窗。关闭C弹窗时,还能看到B弹窗,而不用在A弹窗的基础上通过点击事件再弹出B弹窗。这个时候就需要把关闭的方法当作参数传递给ok回调函数,让调用弹窗组件的人自行控制在什么时候关闭弹窗,这难道不香吗?只不过这个时候可能需要多给弹窗组件传一个参数autoClose来通知它是不是需要前端自行控制什么时候来关闭弹窗,毕竟弹窗组件在大多数情况下都是点击了确定或提交按钮后就直接被关闭了。

beClose(done) {
done();
this.beforeClose();
this.cancel();
}

这段代码是弹窗组件的关闭前before-close方法,element的官方解释是“关闭前的回调,会暂停Dialog的关闭”,官方还给了一个特别的说明:

before-close仅当用户通过点击关闭图标或遮罩关闭Dialog时起效。如果你在footer具名slot里添加了用于关闭Dialog的按钮,

那么可以在按钮的点击回调函数里加入before-close的相关逻辑。

它接收一个参数done,用于关闭Dialog。而this.beforeClose()是用来自定义关闭前的所要做的一些事情的方法。

还有一点需要注意的是:普通组件所有未声明的属性都会被解析到$attrs里面,并自动挂载到组件根元素上面。因为本次封装的弹窗组件的外面已经没有根元素了,也就是标签el-dialog的外面没有再包裹一层div标签,所以前边这就话的意义已经不大了,如果标签el-dialog的外面又包裹了一层div,那么“所有未声明的属性都会被解析到$attrs里面,并自动挂载到组件根元素上面”这句话就有意义了,也就是说这些未声明的属性也会出现在最外层的div上,如果不想让这些未声明的属性也会出现在最外层的div上,那么就可以用inheritAttrs:false来禁止。但本次封装的弹窗组件的外面没有根元素,所以加不加这个inheritAttrs:false都无所谓了。

2、弹窗组件的使用:

<template>
<div>
<el-button @click="open">点我打开</el-button>
<Dialog ref="dialog" :title="title" :width="width" :center="center" :btnTxt="btnTxt" :beforeClose="beforeClose" :content="'这里是中国'"><span>this is a dialog</span></Dialog>
</div>
</template> <script>
import Dialog from "@/components/dialog"; export default {
components: {
Dialog,
},
data() {
return {
width: '500px',
title: '温馨提示',
center: true,
btnTxt: ['取消', '提交'],
};
},
methods: {
open() {
this.$refs.dialog.open(cancel => {
// cancel();
console.log('点击提交按钮了')
});
},
beforeClose(){
console.log('关闭前');
},
}
};
</script>

以上具体的使用方法中:

open() {
this.$refs.dialog.open(cancel => {
// cancel();
console.log('点击提交按钮了')
});
}

这段代码就是用来打开或弹出弹窗组件,这里就是采用ref来获取弹窗组件的open方法,并向弹窗组件的open方法传一个回调函数,而这个回调函数的参数就是组件中ok事件触发时所返回的函数参数cancel,如果不要前端来自行控制弹窗的关闭,则不接收这个cancel参数即可。

封装Vue Element的dialog弹窗组件的更多相关文章

  1. 封装React AntD的dialog弹窗组件

    前一段时间分享了基于vue和element所封装的弹窗组件(封装Vue Element的dialog弹窗组件),今天就来分享一个基于react和antD所封装的弹窗组件,反正所使用的技术还是那个技术, ...

  2. vue+element table的弹窗组件

    在处理表格编辑相关的需求,是需要做一个弹框进行保存的:或者查看表格数据的详细信息时,也是需要做弹窗: 当然 ,这是类似于这样的 ,当然 element 已经帮我们做好 弹窗这一块 主要 我想记录的是 ...

  3. 封装Vue Element的table表格组件

    上周分享了几篇关于React组件封装方面的博文,这周就来分享几篇关于Vue组件封装方面的博文,也好让大家能更好地了解React和Vue在组件封装方面的区别. 在封装Vue组件时,我依旧会交叉使用函数式 ...

  4. 封装Vue Element的form表单组件

    前两天封装了一个基于vue和Element的table表格组件,阅读的人还是很多的,看来大家都是很认同组件化.高复用这种开发模式的,毕竟开发效率高,代码优雅,逼格高嘛.虽然这两天我的心情很糟糕,就像& ...

  5. 封装Vue Element的可编辑table表格组件

    前一段时间,有博友在我那篇封装Vue Element的table表格组件的博文下边留言说有没有那种"表格行内编辑"的封装组件,我当时说我没有封装过这样的组件,因为一直以来在实际开发 ...

  6. vue+element ui中select组件选择失效问题原因与解决方法

    codejing 2020-07-10 09:13:31  652  收藏 分类专栏: Web Vue Element UI 版权 .当表单form赋完值后,如果后续又对form中某一属性值进行操作如 ...

  7. Vue+element UI实现分页组件

    介绍 这是一个是基于element-UI的分页组件基础上,进行了二次封装的分页组件,在展示数据时,该分页组件采用了每显示一页数据,只请求当前页面的数据的请求策略,从而避免了一次性将数据全部请求所造成的 ...

  8. 封装Vue Element的upload上传组件

    本来昨天就想分享封装的这个upload组件,结果刚写了两句话,就被边上的同事给偷窥上了,于是在我全神贯注地写分享的时候他就神不知鬼不觉地突然移动到我身边,腆着脸问我在干啥呢.卧槽你妈,当场就把我吓了一 ...

  9. 【vue】vue +element 搭建项目,组件之间通信

    父子组件通信 父 通过props属性给 子传递数据 子 操作 父  this.$parent.XXX 子通过$emit传递参数 或者通过vue-bus vue-bus既可以实现父子组件之间的通信,也可 ...

随机推荐

  1. luogu P6097 子集卷积 FST FWT

    LINK:子集卷积 学了1h多 终于看懂是怎么回事了(题解写的不太清楚 翻了好几篇博客才懂 一个需要用到的性质 二进制位为1个数是i的二进制数s 任意两个没有子集关系.挺显然. 而FST就是利用这个性 ...

  2. Python selenium 三种消息框处理和浏览器(页面跳转)句柄处理

    1. alert: 警告框,只是一个提示信息,只有一个确定按钮,起提示用户的作用: 2.confirm: 确认框,确定和取消按钮会带来不同的结果.点击确定会执行操作,点击取消按钮会取消操作: 3.pr ...

  3. 有关WebSocket必须了解的知识

    一.前言 最近之前时间正好在学习java知识,所以自个想找个小项目练练手,由于之前的ssm系统已经跑了也有大半年了,虽然稀烂,但是功能还是勉强做到了,所以这次准备重构ssm系统,改名为postCode ...

  4. iOS苹果美区 Apple ID 账号最新注册教程,iPhone用户务必收藏!

    编の语 前言 今天杀手宝宝出一个注册美区ID的教程,这是目前注册苹果美区ID最快的方法,所有人适合使用! 提の示 温馨提示: 所有内容均免费分享,部分资源来自于 网络,如与版权问题联系宝宝处理! 知道 ...

  5. Java实现邮箱验证码

    前言 相比于java实现短信验证码,邮箱验证码就简单了许多,目前只是简单的利用java发送自定义内容至指定邮箱,等过几天再弄短信和邮箱验证码Web版本的.查询网上资料,得知相比于网易邮箱,QQ邮箱是最 ...

  6. 如何利用Python在网上接单,兼职也能月薪过万

  7. FSAF

    Feature Selective Anchor-Free Module for Single-Shot Object Detection https://zhuanlan.zhihu.com/p/5 ...

  8. python使用zipfile递归压缩和解压缩文件

    import shutil,zipfile,os class ToolModel(object): def dfs_get_zip_file(self,input_path, result, igno ...

  9. elementUI 表单清空问题

    在使用表单的清空方法时,我们需要注意几个问题: 1.我们需要为每个form-item加上prop属性,要不然无法清空(大部分的问题就是出在这) 2.resetFields()方法是重置表单,重置为默认 ...

  10. RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers的双语版

    RFC2474 - Definition of the Differentiated Services Field (DS Field) in the IPv4 and IPv6 Headers英文版 ...