这期内容当中小编将会给大家带来有关vue中怎么实现一个模态框组件,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
组件结构
<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>
上述就是小编为大家分享的vue中怎么实现一个模态框组件了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。