当前位置: 首页 > 科技观察

如何用vue实现模态框组件

时间:2023-03-15 17:03:57 科技观察

基本上每个项目都需要用到模态框组件。由于在最近的项目中,alert组件和confirm是两个完全不同的设计,所以我把它们分为两个组件,本文主要讨论confirm组件的实现。组件结构模态框结构划分into头部、内部区域和操作区域三部分都提供了插槽,可以根据需要自定义modal{position:fixed;left:0;top:0;right:0;bottom:0;z-index:1001;-webkit-overflow-scrolling:touch;outline:0;overflow:scroll;margin:30/@rateauto;}.modal-dialog{position:absolute;left:50%;top:0;变换:翻译(-50%,0);宽度:690/@rate;填充:50/@rate40/@rate;背景:#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(){letmodal=this.modalOptions;modal={title:modal.title||'prompt',text:modal.text,showCancelButton:typeofmodal.showCancelButton==='undefined'?true:modal.showCancelButton,cancelButtonClass:modal.cancelButtonClass?modal.showCancelButton:'btn-default',cancelButtonText:modal.cancelButtonText?modal.cancelButtonText:'Cancel',showConfirmButton:typeofmodal.showConfirmButton==='undefined'?true:modal.cancelButtonClass,confirmButtonClass:modal.confirmButtonClass?模态。confirmButtonClass:'btn-active',confirmButtonText:modal.confirmButtonText?modal.confirmButtonText:'OK',};returnmodal;},},},这里定义了界面的参数,可以自定义标题,内容,是否显示按钮以及按钮的样式,使用一个computed作为控件modal参数框默认值data(){return{show:false,//是否显示模态框resolve:'',reject:'',promise:'',//保存promise对象};},methods:{/***OK,确定promise为完成状态*/submit(){this.resolve('submit');},/***Close,确定promise为拒绝状态*@paramtype{number}关闭方式0表示关闭按钮关闭,1表示取消按钮关闭*/close(type){this.show=false;this.reject(type);},/***显示确认弹出窗口,并创建一个承诺对象*@returns{Promise}*/confirm(){this.show=true;this.promise=newPromise((resolve,reject)=>{this.resolve=resolve;this.reject=reject;});returnthis.promise;//返回promise对象,给父组件调用},},三个方法都是defin在模态框中编辑。核心部分,confirm方法,是定义在模态框内部的一个方法,但是它是为使用模态框的父组件调用的。该方法返回一个promise对象,并将resolve和reject存储在模态组件的数据中。当点击取消按钮时,判断为拒绝状态,关闭模态框。当点击确定按钮时,确定为解析状态。模态框没有关闭,调用模态组件的父组件回调处理完成后手动关闭模态框。调用this.$refs.dialog.confirm().then(()=>{//点击确定按钮callback的回调处理();this.$refs.dialog.show=false;}).catch(()=>{//点击取消按钮回调的回调处理();});使用v-ref创建索引,获取模态框组件内部的方法非常方便。这样一个模态框组件就完成了。其他实现方法在模态框组件中,比较难实现的应该是点击确定和取消按钮时父级的回调处理。我在做这个组件的时候,也参考了一些实际的实现方案。使用事件转发的方法是我同事实现的。在之前的项目中使用过,使用$dispatch和$broadcast来调度或者广播事件。根组件首先从dispatch接收到transmit事件,然后将transmit事件传递的eventName广播给events:{/***forwardevent*@param{string}eventName事件名*@param{object}arg事件参数*@return{null}*/'transmit':function(eventName,arg){this.$broadcast(eventName,arg);}},后面是模态框组件接收父组件传来的OK和取消按钮的触发事件的名称,点击取消和确认按钮时触发//接收事件,获取取消和确认按钮事件的事件名称:{'tip':function(obj){this.events={取消: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监听确认或取消按钮触发的事件,触发后的事件回调,这个方法是不是看着晕?所以vue2.0取消了$dispatch和$broadcast,虽然我们最近的项目还在用1.0,但是不再使用$dispatch和$broadcast,方便以后升级。使用emit来从vue-bootstrap-modal触发这个方法,当你点击取消和确认按钮时,分别发出一个事件,直接在组件上监听这个事件,这种方式的好处是事件更容易追踪。//确定按钮ok(){this.$emit('ok');if(this.closeWhenOK){this.show=false;}},//取消按钮cancel(){this.$emit('cancel');this.show=false;},调用:ModalText但是当我们使用的时候我们经常遇到这样的场景。在一个组件内部,经常使用多个对话框。对话框可能只有不同的文本和不同的回调。这时候就需要为模板中的每个对话框写一次。modal>,有点麻烦。如果不想每次都写,可以使用v-for遍历。本文关于vue弹窗组件的一些思考,已经和笔者进行了探讨。你可以参考他们。参考vue.jsdynamiccreatenestmodales6Promiseobjectvue-bootstrap-modalvue弹窗组件的一些思考