uniapp全局对象(uniapp全局弹窗(APP端))
导读: uniapp自带的提示框不符合我们的要求,需要自己写一个提示框,且全局通用。...
uniapp自带的提示框不符合我们的要求 ,需要自己写一个提示框 ,且全局通用 。
解决思路: 使用 plus.nativeObj 来绘制窗口以及事件监听 。 官方文档
1. 首先创建一个整个屏幕的控件,作为一个父容器 。 此时还看不到任何东西
let screenHeight = uni.getSystemInfoSync().screenHeight; let style = { width:100%, height: (screenHeight + px), left:0px, top:0px }; // 创建原生控件对象 // 参数1: id // 参数2: 控件的样式 let view = new plus.nativeObj.View(showModalView,style);2. 绘制遮罩层
view.draw([ {tag:rect,id:modal,color:`rgba(0,0,0,0.4)`,position:{top:0px,left:0px,width:100%,height:100%}} ]); { tag:rect, // 绘制矩形 id:modal, // 控件id color:`rgba(0,0,0,0.4)`, // 背景色 position:{top:0px,left:0px,width:100%,height:100%} // 位置和大小样式 }view.draw(tags); 在控件上绘制 ,传入绘制对象 。
绘制对象文档 可绘制图片 、矩形区域 、文本等内容 。
3.绘制通知框样式
view.draw([ {tag:rect,id:modal,color:`rgba(0,0,0,0.4)`,position:{top:0px,left:0px,width:100%,height:100%}}, {tag:rect,id:content,rectStyles:{borderWidth:2px,radius:8px,color:`rgba(36,34,56,1)`},position:{top:startTop+px,left:startLeft+px,width:width+px,height:height+px}}, ]); { tag:rect, id:content, // 矩形的样式 rectStyles:{borderWidth:2px,radius:8px,color:`rgba(36,34,56,1)`}, // 位置和大小. 下面的变量是根据屏幕宽高手动计算的 position:{top:startTop+px,left:startLeft+px,width:width+px,height:height+px} } interface RectStyles { attribute String color; attribute String radius; attribute String borderColor; attribute String borderWidth; }4. 绘制标题和内容
view.draw([ {tag:rect,id:modal,color:`rgba(0,0,0,0.4)`,position:{top:0px,left:0px,width:100%,height:100%}}, {tag:rect,id:content,rectStyles:{borderWidth:2px,radius:8px,color:`rgba(36,34,56,1)`},position:{top:startTop+px,left:startLeft+px,width:width+px,height:height+px}}, {tag:font,id:title,text:modelInfo.tit,textStyles:{size:16px,color:#fff},position:{top:titleTop+px,left:startLeft+px,width:width+px,height:titleHeight+px}}, {tag:font,id:text,text:modelInfo.content,textStyles:{size:14px,color:#fff,whiteSpace:normal,align:modelInfo.align},position:{top:contentTop+px,left:startLeft+px,width:width+px,height:contentHeight+px}}, // 这个是内容和底部按钮的分割线 {tag:rect,id:line,color:rgba(255,255,255,0.3),position:{top:lineTop+px,left:startLeft+px,width:width+px,height:0.5px}}, ]); { tag:font, // 绘制文字 id:title, text:modelInfo.tit, // 文字内容 textStyles:{size:16px,color:#fff}, position:{top:titleTop+px,left:startLeft+px,width:width+px,height:titleHeight+px} },5. 创建确认按钮控件
我们需要给确认按钮设置点击事件 ,所以它要作为一个新的控件 ,而不是再刚刚的控件上继续绘制 。
// 确认 let viewconfirm=new plus.nativeObj.View(confirm, { width:modelInfo.delCancel?width+px:40%, height:buttonHeight+px, top:lineTop+px, left:modelInfo.delCancel?startLeft+px:halfWidthForGlobal +px, backgroundColor:rgba(255,255,255,0), }, ); viewconfirm.draw([ {tag:font,id:confirm,text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:14px}}, ]);设置点击事件
viewconfirm.addEventListener("click",(e)=>{ // 发送事件 this.$event({res:true,types:confirm}); // 隐藏当前控件(关闭) this.hide(); },false);将 viewconfirm和view显示出来:
function show(){ this.view.show(); this.confirmModel.show(); }下面就是将这些挂载到Uni上就可以了 。
下面是项目中的完整代码:
index.js 用于绘制
// show_modal/index.js export class show_model{ constructor(option={}) { this.bodyModel=null; this.cancelModel=null; this.confirmModel=null; this.pageHeight=uni.getSystemInfoSync().screenHeight; this.pageWidth = uni.getSystemInfoSync().screenWidth; let opacity = option.opacity || 0.4; let model_tit=option.title||温馨提示; let model_content=option.content||"内容" let clickEvent=option.IsclickEvent||false; let cancelVal=option.cancelVal||取消; let confirmVal=option.confirmVal||确认; let cancelColor=option.cancelColor||#fff; // 取消 let confirmColor=option.confirmColor||#fff; // 确认 let delCancel=option.delCancel||false; let align=option.align||"center"; let fn = ()=>{}; this.$event = option.$event || fn; let backOff=option.backOff||false; //#ifdef APP-PLUS this.creatView({height:`${this.pageHeight}px`,top:0},opacity,clickEvent,{tit:model_tit,content:model_content,cancelVal,confirmVal,confirmColor,cancelColor,delCancel,align}) if(!backOff){ this.backbtn(); } //#endif } backbtn(){ let that=this; plus.key.addEventListener(backbutton, function (e) { that.hide(); },false) } //生成提示框view creatView(style,opa,clickEvent,modelInfo){ style = { left:0px, width:100%, ...style } let platform = plus.os.name.toLowerCase(); let view = new plus.nativeObj.View(showModalView,style); let width = 300; let height = 150; let titleHeight = 20; let contentHeight = 60; let startTop = (this.pageHeight - height) / 2; let startLeft = (this.pageWidth - width) / 2; let titleTop = startTop + 10; let contentTop = titleTop+30; let lineTop = startTop + height - 40; let buttonHeight = 40; let halfWidth = width / 2; let halfWidthForGlobal = startLeft + halfWidth; if(platform == "ios"){ view.draw([ {tag:rect,id:modal,color:`rgba(0,0,0,${opa})`,position:{top:0px,left:0px,width:100%,height:100%}}, {tag:rect,id:content,rectStyles:{borderWidth:2px,radius:8px,color:`rgba(36,34,56,1)`},position:{top:startTop+px,left:startLeft+px,width:width+px,height:height+px}}, {tag:font,id:title,text:modelInfo.tit,textStyles:{size:16px,color:#fff},position:{top:titleTop+px,left:startLeft+px,width:width+px,height:titleHeight+px}}, {tag:font,id:text,text:modelInfo.content,textStyles:{size:14px,color:#fff,whiteSpace:normal,align:modelInfo.align},position:{top:contentTop+px,left:startLeft+px,width:width+px,height:contentHeight+px}}, {tag:rect,id:line,color:rgba(255,255,255,0.3),position:{top:lineTop+px,left:startLeft+px,width:width+px,height:0.5px}}, {tag:rect,id:line2,color:rgba(255,255,255,0.3),position:{top:lineTop+px,left:+halfWidthForGlobal+px,width:modelInfo.delCancel?0px:0.5px,height:modelInfo.delCancel?0px:buttonHeight+px}} ]); }else{ view.draw([ {tag:rect,id:modal,color:`rgba(0,0,0,${opa})`,position:{top:0px,left:0px,width:100%,height:100%}}, {tag:rect,id:content,rectStyles:{borderWidth:2px,radius:8px,color:`rgba(36,34,56,1)`},position:{top:startTop+px,left:startLeft+px,width:width+px,height:height+px}}, {tag:font,id:title,text:modelInfo.tit,textStyles:{size:16px,color:#fff},position:{top:titleTop+px,left:startLeft+px,width:width+px,height:titleHeight+px}}, {tag:font,id:text,text:modelInfo.content,textStyles:{size:14px,color:#fff,whiteSpace:normal,align:modelInfo.align},position:{top:contentTop+px,left:startLeft+px,width:width+px,height:contentHeight+px}}, {tag:rect,id:line,color:rgba(255,255,255,0.3),position:{top:lineTop+px,left:startLeft+px,width:width+px,height:0.5px}}, {tag:rect,id:line2,color:rgba(255,255,255,0.3),position:{top:lineTop+px,left:halfWidthForGlobal+px,width:modelInfo.delCancel?0px:0.5px,height:modelInfo.delCancel?0px:buttonHeight+px}} ]); } var num = 0.55; if(platform == "ios"){ num = 0.57 } if(!modelInfo.delCancel){ // 取消 let viewCancel=new plus.nativeObj.View(cancel,{width:halfWidth+px,height:buttonHeight+px,top:lineTop+px,left:startLeft+px,backgroundColor:rgba(255,255,255,0)}); viewCancel.draw([ {tag:font,id:cancel,text:modelInfo.cancelVal,textStyles:{color:modelInfo.cancelColor,size:14px}}, ]); viewCancel.addEventListener("click",(e)=>{ this.$event({res:false,types:cancel}); this.hide(); },false); this.cancelModel=viewCancel; } // 确认 let viewconfirm=new plus.nativeObj.View(confirm, { width:modelInfo.delCancel?width+px:40%, height:buttonHeight+px, top:lineTop+px, left:modelInfo.delCancel?startLeft+px:halfWidthForGlobal +px, backgroundColor:rgba(255,255,255,0), }, ); viewconfirm.draw([ {tag:font,id:confirm,text:modelInfo.confirmVal,textStyles:{color:modelInfo.confirmColor,size:14px}}, ]); viewconfirm.addEventListener("click",(e)=>{ this.$event({res:true,types:confirm}); this.hide(); },false); //点击蒙布 if(clickEvent){ view.addEventListener("click", (e) => { this.$event({res:false,types:cover}); this.hide(); }, false); } this.bodyModel=view; this.confirmModel=viewconfirm; } showModalAnimationClose(){ var options = {type:pop-out,duration:300}; plus.nativeObj.View.startAnimation(options,{view:this.bodyModel},{view:this.cancelModel},{view:this.viewconfirm},function(){ console.log(plus.nativeObj.View.startAnimation动画结束); // 关闭原生动画 plus.nativeObj.View.clearAnimation(); }); } showModalAnimationOpen(){ var options = {type:pop-in,duration:1000}; plus.nativeObj.View.startAnimation(options,{view:this.bodyModel},{view:this.cancelModel},{view:this.viewconfirm},function(){ console.log(plus.nativeObj.View.startAnimation动画结束); // 关闭原生动画 plus.nativeObj.View.clearAnimation(); }); } show(){ this.showModalAnimationOpen(); this.bodyModel.show(); if(this.cancelModel){ this.cancelModel.show(); } this.confirmModel.show(); } hide(){ this.showModalAnimationClose(); this.bodyModel.hide(); if(this.cancelModel){ this.cancelModel.hide(); } this.confirmModel.hide(); } } export default show_modelshow_modal.js: 用于创建promise对象并挂载
// show_modal/xt_show_modal.js import show_modal from ./index.js const xt_show_modal = { install: function(Vue) { const show_modal_fun=function(op={}){ //#ifdef APP-PLUS return new Promise((resolve, reject)=>{ let ssm=new show_modal({ ...op, $event:function(e){ if(e.res){ resolve(e); }else{ reject(e); } } }); ssm.show(); Vue.prototype.$hide=function(){ ssm.hide(); } }) //#endif // 适应H5 //#ifdef H5 var promise=uni.showModal({ title: op.title, content: op.content, showCancel: !op.delCancel, cancelText: op.cancelVal, confirmText: op.confirmVal, }); return new Promise((resolve,reject)=>{ promise.then(data=>{ var [err, res] = data; if(res.confirm){ resolve() }else{ reject(); } }) }) //#endif } // $showModal挂载到uni对象上 uni.$showModal = show_modal_fun Vue.prototype.$showModal = show_modal_fun } }; export default xt_show_modal;main.js中挂载
// 自定义showModal组件 import xt_show_modal from @/component/show_modal/xt_show_modal.js Vue.use(xt_show_modal);使用:
// showModel的使用 uni.$showModal({ title:"", //可选,不填则不显示 content:未知错误 ,请联系管理员!, delCancel: true, confirmVal: 知道了, // 可选 cancelVal:取消, // 可选 }).then(res=>{ // 点击确认按钮点击事件 }).catch(res=>{ // 点击取消按钮点击事件 });创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!