用vue实现模态框组件
基本上每个项目都需要用到模态框组件,由于在最近的项目中,alert组件和confirm是两套完全不一样的设计,所以我将他们分成了两个组件,本文主要讨论的是confirm组件的实现。
组件结构
<template><div class="modal" v-show="show" transition="fade"><div class="modal-dialog"><div class="modal-content"><!--头部--><div class="modal-header"><slot name="header"><p class="title">`modal`.`title`</p></slot><a v-touch:tap="close(0)" class="close" href="javascript:void(0)"></a></div><!--内容区域--><div class="modal-body"><slot name="body"><p class="notice">`modal`.`text`</p></slot></div><!--尾部,操作按钮--><div class="modal-footer"><slot name="button"><a v-if="modal.showCancelButton" href="javascript:void(0)" class="button `modal`.`cancelButtonClass`" v-touch:tap="close(1)">`modal`.`cancelButtonText`</a><a v-if="modal.showConfirmButton" href="javascript:void(0)" class="button `modal`.`confirmButtonClass`" v-touch:tap="submit">`modal`.`confirmButtonText`</a></slot></div></div></div></div><div v-show="show" class="modal-backup" transition="fade"></div></template>
模态框结构分为三部分,分别为头部、内部区域和操作区域,都提供了slot,可以根据需要定制。
样式
.modal { position: fixed; left: 0; top: 0; right: 0; bottom: 0; z-index: 1001; -webkit-overflow-scrolling: touch; outline: 0; overflow: scroll; margin: 30/@rate auto; }.modal-dialog { position: absolute; left: 50%; top: 0; transform: translate(-50%,0); width: 690/@rate; padding: 50/@rate 40/@rate; background: #fff; }.modal-backup { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1000; background: rgba(0, 0, 0, 0.5); }
这里只是一些基本样式,没什么好说的,这次项目是在移动端,用了淘宝的自适应布局方案,@rate是切稿时候的转换率。
接口定义
/*** modal 模态接口参数* @param {string} modal.title 模态框标题* @param {string} modal.text 模态框内容* @param {boolean} modal.showCancelButton 是否显示取消按钮* @param {string} modal.cancelButtonClass 取消按钮样式* @param {string} modal.cancelButtonText 取消按钮文字* @param {string} modal.showConfirmButton 是否显示确定按钮* @param {string} modal.confirmButtonClass 确定按钮样式* @param {string} modal.confirmButtonText 确定按钮标文字*/props: ['modalOptions'],computed: { /*** 格式化props进来的参数,对参数赋予默认值*/ modal: {get() {let modal = this.modalOptions;modal = { title: modal.title || '提示', text: modal.text, showCancelButton: typeof modal.showCancelButton === 'undefined' ? true : modal.showCancelButton, cancelButtonClass: modal.cancelButtonClass ? modal.showCancelButton : 'btn-default', cancelButtonText: modal.cancelButtonText ? modal.cancelButtonText : '取消', showConfirmButton: typeof modal.showConfirmButton === 'undefined' ? true : modal.cancelButtonClass, confirmButtonClass: modal.confirmButtonClass ? modal.confirmButtonClass : 'btn-active', confirmButtonText: modal.confirmButtonText ? modal.confirmButtonText : '确定',}; return modal;},}, },
这里定义了接口的参数,可以自定义标题、内容、是否显示按钮和按钮的样式,用一个computed来做参数默认值的控制。
模态框内部方法
data() { return {show: false, // 是否显示模态框resolve: '',reject: '',promise: '', // 保存promise对象}; }, methods: { /*** 确定,将promise断定为完成态*/submit() { this.resolve('submit');}, /*** 关闭,将promise断定为reject状态* @param type {number} 关闭的方式 0表示关闭按钮关闭,1表示取消按钮关闭*/close(type) { this.show = false; this.reject(type);}, /*** 显示confirm弹出,并创建promise对象* @returns {Promise}*/confirm() { this.show = true; this.promise = new Promise((resolve, reject) => { this.resolve = resolve; this.reject = reject;}); return this.promise; //返回promise对象,给父级组件调用}, },
在模态框内部定义了三个方法,最核心部分confirm方法,这是一个定义在模态框内部,但是是给使用模态框的父级组件调用的方法,该方法返回的是一个promise对象,并将resolve和reject存放于modal组件的data中,点击取消按钮时,断定为reject状态,并将模态框关闭掉,点确定按钮时,断定为resolve状态,模态框没有关闭,由调用modal组件的父级组件的回调处理完成后手动控制关闭模态框。
调用
<!-- template --><confirm v-ref:dialog :modal-options.sync="modal"></confirm><!-- methods -->this.$refs.dialog.confirm().then(() => {// 点击确定按钮的回调处理callback();this.$refs.dialog.show = false; }).catch(() => {// 点击取消按钮的回调处理callback(); });
用v-ref创建一个索引,就很方便拿到模态框组件内部的方法了。这样一个模态框组件就完成了。
其他实现方法
在模态框组件中,比较难实现的应该是点击确定和取消按钮时,父级的回调处理,我在做这个组件时,也参考了一些其实实现方案。
使用事件转发
这个方法是我的同事实现的,用在上一个项目,采用的是$dispatch和$broadcast来派发或广播事件。
首先在根组件接收dispatch过来的transmit事件,再将transmit事件传递过来的eventName广播下去
events: { /*** 转发事件* @param {string} eventName 事件名称* @param {object} arg 事件参数* @return {null}*/'transmit': function (eventName, arg) {this.$broadcast(eventName, arg);} },
其次是模态框组件内部接收从父级组件传递过来的确定和取消按钮所触发的事件名,点击取消和确定按钮的时候触发
// 接收事件,获得需要取消和确定按钮的事件名events: { 'tip': function(obj) { this.events = {cancel: obj.events.cancel,confirm: obj.events.confirm}} }// 取消按钮cancel:function() { this.$dispatch('transmit',this.events.cancel); }// 确定按钮submit: function() { this.$dispatch('transmit',this.events.submit); }
在父级组件中调用模态框如下:
this.$dispatch('transmit','tip',{events: {confirm: 'confirmEvent'} });this.$once('confirmEvent',function() {callback(); }
先是传递tip事件,将事件名传递给模态框,再用$once监听确定或取消按钮所触发的事件,事件触发后进行回调。
这种方法看起来是不是很晕?所以vue 2.0取消了$dispatch和$broadcast,我们在最近的项目中虽然还在用1.0,但是也不再用$dispatch和$broadcast,方便以后的升级。
使用emit来触发
这种方法来自vue-bootstrap-modal,点击取消和确定按钮的时候分别emit一个事件,直接在组件上监听这个事件,这种做法的好处是事件比较容易追踪。
// 确定按钮ok () { this.$emit('ok'); if (this.closeWhenOK) { this.show = false;} },// 取消按钮cancel () { this.$emit('cancel'); this.show = false; },
调用:
<modal title="Modal Title" :show.sync="show" @ok="ok" @cancel="cancel">Modal Text </modal>
但是我们在使用的时候经常会遇到这样的场景,在一个组件的内部,经常会用到多个对话框,对话框可能只是文字有点区别,回调不同,这时就需要在template中为每个对话框都写一次,有点麻烦。
用vue实现模态框组件相关推荐
- 如何用vue实现模态框组件
基本上每个项目都需要用到模态框组件,由于在最近的项目中,alert组件和confirm是两套完全不一样的设计,所以我将他们分成了两个组件,本文主要讨论的是confirm组件的实现. 组件结构 < ...
- vue模态框组件拿不到dom元素
今天在写模态框的组件时,在一个页面引入了模态框组件.但是模态框设置初始是不显示的,然后我在模态框组件里面的mouted里面拿到dom元素,按理来说mouted都已经加载完元素了,但是我不管是通过doc ...
- uniapp vue nvue 模态框遮罩
uniapp vue nvue 模态框遮罩 以前 纯 Vue 开发的时候:模态框遮罩就是这么写的 .popBack{position: fixed;top: 0;left: 0;z-index: ...
- 详细介绍React模态框组件react-modal
1,介绍 该组件实现了模态框的一些效果. 这是react-modal官网的配置参数. 模态框的手动实现,并不算太难,这个组件用着还不错. 2,配置参数介绍 import React, { Compon ...
- 可自定义的vue下拉框组件
创建Select.vue组件 //创建Select.vue组件<template><div class="selects"><!-- 选择框 --&g ...
- Vue的模态框中实现 根据详细地址定位经纬度
最近在项目中遇到这样一个需求,在新增商品的模态框中,根据拿到的地址在地图上显示具体位置,并把经纬度给后台. 如图,选择供应商之后在2的input框中会显示详细的地址,根据后台返回的详细地址地图上定位到 ...
- Vue笔记(五)—— Vue render渲染/组件嵌套之iView官网案例改写Table表格组件及Modal弹窗/对话框/模态框组件内容自定义详解
缺乏耐心的读者请主要关注标红部分! 因部分内容自动转为代码格式,所以代码部分请主要关注注释部分! 1.Table表格组件内容自定义: 官网Table表格组件部分示例代码: columns12: [{t ...
- vue弹出框组件封装
新学vue,参考别人封装弹出层组件.好用! 1.你需要先建一个弹出框的模板: //首先创建一个mack.vue<template><div class="mack" ...
- vue中下拉框组件的封装
原理 vue element中,需要封装一个对应的下拉款组件. 第一步:在api_domain.js中添加后台的请求接口 //获取下拉框的接口 从redis中domainGetDomainKeyRed ...
最新文章
- Debian 新维护人员手册
- 电商购物网站开发需要注意这些问题
- 损失函数-经验风险最小化-结构风险最小化
- linux权限管理(chown、chgrp、chomd)
- UILable的text设置中划线(删除线)
- 图解机器学习读书笔记-CH6
- delphi的接口support_学习到的关于Delphi的接口
- 【矩阵乘法】Quad Tiling(poj 3420)
- Qt实现对json文件的解析
- VS Code 中的文件添加图标的插件vscode-icons
- iOS 权限判断 跳转对应设置界面
- python3列表推导式矩阵转置_python3进阶之推导式1之列表(list)推导式(comprehensions)...
- 不使用自动注解方式来生成mapper,采用原生方式来生成mapper
- 【Flask】flask不能访问静态文件问题
- bfs和dfs:poj2386和leetcode130
- 商品分析是什么?该怎么做(入门版)
- DHT,种子转磁力算法 种子info_hash 代码亲测
- 广东工业大学华立学院c语言试题,广东工业大学华立学院考试试卷《高频电子线路》-2015.doc...
- 简要分析VB6.0和VB.NET区别
- Mkdocs部署静态网页至GitHub pages配置说明(mkdocs.yml)
热门文章
- LeetCode-19 删除链表的倒数第N个节点
- CSS改变插入光标颜色
- 微信小程序setTimeout自动跳转页面
- 解决Adobe Animate CC 中文版非中文的BUG
- LASSOS方程--图像降噪
- centos 6.5 安装 lamp 后mysql不能启动_Lamp的搭建--centos6.5下安装mysql
- webpack学习之路(四)webpack-hot-middleware实现热更新
- 用户模式 linux救援单用户 (补充)
- 《软件工艺师:专业、务实、自豪》一2.8 小结
- RecyclerView加载不同view实现效果--IT蓝豹