# propt **Repository Path**: queling/propt ## Basic Information - **Project Name**: propt - **Description**: 弹出窗组件,根据不同配置,可以展现出message信息提示框,alert弹出窗,totast轻提示,dialog弹出窗 - **Primary Language**: JavaScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2021-09-01 - **Last Updated**: 2021-09-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 【openHarmony】基于JSUI实现的弹出对话框 ## 前言 翻阅了一遍文档,发现原本的JSUI里面的弹出对话框比较单一,不能满足一些业务开发需求, 于是就自己分装了一个,包含了message信息提示框,alert弹提示,toatst轻提示,dialog对话框 ## 实现效果 ![](gif/message.gif) ![](gif/dialog.gif) ## 实现思路 - message 信息提示框 * 根基传入提示内容以及图片展示在屏幕的中间 * 每次点击即可显示或者隐藏 - alert 弹出提示 * 随机数字+随机大小写字母 * 文本内容+关闭按钮 * 点击关闭按钮会关不提示 * 事件:点击刷新 - toast轻提示 * 文本内+图片 * 宽高150x150 * 1500毫秒之后会自动关闭 - dianlog 对话框 * 带右反馈操作按钮,取消和确定按钮 * 点击取消或者确定按钮,dialog会自动关闭 - 组件抛出的事件 * close 关闭弹窗的事件,在message,toast无效 * cancel 取消事件 * confirm 确定事件 * cancel,confirm 时间只会在dialog有效 - Tips : * message 根据内容自动撑开宽高 * diallog 宽度是80% * alert 宽度是屏幕的宽度-20 * toast 宽高150x150 ## 实现 ### hml布局 - 布局图片 ![](./gif/html.png) - hml页面布局分为两部分,一部分消息提示框,一部分dialog对话框 * 根据type传入的值,显示不同的弹窗 * 传入dialog则会显示对话框,传入其他的会改变布局显示提示框 * 所有type类型都会默人有四个样式,success,warning,info,error - 详细代码 ```html
``` ### js组件内部实现 - 元素居中,需要获取到元素的宽度和屏幕的宽度,计算方法:屏幕宽度-元素宽度之间的差值除以2;注意获取元素信息需要在定时器内延时一段时间后才能获取到 ```js offsetInit{ this.getPhoneInfo(); if(this.type=="message" || this.type=="alert" || this.type=="toast"){ var el=this.$element("messagesContent").getBoundingClientRect(); }else if(this.type=="dialog"){ var el=this.$element("dialogBox").getBoundingClientRect(); } let offsetLeft=(this.phoneInfo.width-el.width)/2; let offsetTop=this.offsetTop; if(this.phoneInfo){ this.offsetLeft=offsetLeft; } if(offsetTop=="center"){ this.offsetTop=(this.phoneInfo.height-el.height)/2 } ``` - 默认的情景 success,warning,info,error ```js // 弹框类型颜色 propt_type(){ if(this.proptType=="success"){ this.bgColor="rgba(7,193,96,0.2)"; }else if(this.proptType=="warning"){ this.bgColor="rgba(230,162,60,0.2)"; }else if(this.proptType=="error"){ this.bgColor="rgba(245,108,108,0.2)"; }else if(this.proptType=="info"){ this.bgColor="rgba(147,147,153,0.2)"; } if(this.proptType=="success"){ this.color="#07c160"; }else if(this.proptType=="warning"){ this.color="#e6a23c"; }else if(this.proptType=="error"){ this.color="#f56c6c"; }else if(this.proptType=="info"){ this.color="#909399"; } this.tColor=this.color; this.tBgColor=this.bgColor; }, ``` - 父组件需要传递给子组件的自定义的数据 ```js // 自动关闭时长 time:{default:1500}, // 弹窗是否显示 isShow: {default: false}, // 弹框类型:message消息提示框;alert警告框;toast请提示 ;dialog弹出框 type:{default:"message"}, // 提示内容信息 text:{default:"信息内容"}, // 提示类型:success,warning,error,info proptType:{default:"success"}, // 背景色 bgColor:{default:""}, // 文字颜色 color:{default:""}, // 弹窗距离顶部位置,如果传递center,会垂直水平居中 offsetTop:{default:0}, // 小图标 icon:{default:""}, // 是否显示关闭按钮 isClose:{default:false}, // 确定按钮文本内容 confirmBtn:{default:"确认"}, // 取消按钮文本内容 cancelBtn:{default:"取消"} ``` - 弹窗宽度,以及对其方式 ```js setWidth(){ if(this.type=="alert"){ if(this.phoneInfo){ this.width=this.phoneInfo.width-20; } this.height=null; this.iconWidth=25; this.iconHeight=25; this.isClose=true; this.direction="row"; this.justifyContent="flex-start"; } else if(this.type=="message"){ this.width=null; this.height=null; this.iconWidth=25; this.iconHeight=25; this.isClose=false; this.direction="row"; this.justifyContent="flex-start"; }else if(this.type=="toast"){ this.width=150; this.height=150; this.iconWidth=60; this.iconHeight=60; this.direction="column"; this.justifyContent="center"; this.isClose=false; } }, ``` - 自动关闭 ```js // 关闭弹窗 close(){ this.isMessage=false; this.isDialog=false; this.isShow=false; this.$emit("close",this.isShow) }, // 自动关闭 autoClose(){ if(this.time>0){ if(this.isShow==true || this.isMessage==true || this.isDialog==true){ this.timer=setTimeout(()=>{ this.isFlag=false; this.close(); clearTimeout(this.timer); },this.time); } } }, ``` - 详细代码 ```js // propt-tips.js import device from '@system.device'; export default { data(){ return { // 消息提示框是否显示 isMessage:false, // 对话框是否显示 isDialog:false, // 设备信息 phoneInfo:null, // 弹窗距离左侧位置 offsetLeft:0, // 節流閥 timer:null, // 是否运行重复点击 isFlag:false, // 右侧边距,为关闭按钮留下位置 paddingRight:10, // 弹窗宽度 width:null, height:null, // 对齐方式 direction:"row", justifyContent:"flex-start", // icon宽高 iconWidth:25, iconHeight:25, tColor: this.color, tBgColot: this.bgCcolor } } , props:{ // 自动关闭时常 time:{default:1500}, // 弹窗是否显示 isShow: {default: false}, // 弹框类型:message消息提示框;alert警告框;toast请提示 ;dialog弹出框 type:{default:"message"}, // 提示内容信息 text:{default:"信息内容"}, // 提示类型:success,warning,error,info proptType:{default:"success"}, // 背景色 bgColor:{default:""}, // 文字颜色 color:{default:""}, // 弹窗距离顶部位置,如果传递center,会垂直水平居中 offsetTop:{default:0}, // 小图标 icon:{default:""}, // 是否显示关闭按钮 isClose:{default:false}, // 确定按钮文本内容 confirmBtn:{default:"确认"}, // 取消按钮文本内容 cancelBtn:{default:"取消"} }, onInit() { this.getPhoneInfo(); this.$watch("isShow","isShowWatch"); this.$watch("type","typeWatch") this.$watch("color","colorWatch") this.$watch("bgColor","bgColorWatch") this.type_init(); this.propt_type(); if(this.isClose==true){ this.paddingRight=50 }else{ this.paddingRight=10 } setTimeout(()=>{ this.offsetInit(); },50) }, // 弹出框类型初始化 type_init(){ if(this.isFlag==false){ this.isFlag==true; if(this.isShow==true){ if(this.type=="message" || this.type=="alert" || this.type=="toast"){ this.isDialog=false; this.isMessage=!this.isMessage; }else if(this.type=="dialog"){ this.isMessage=false; this.isDialog=!this.isDialog; } }else{ this.isMessage=false; this.isDialog=false; }; } this.setWidth(); this.autoClose(); setTimeout(()=>{ this.offsetInit(); },50); this.$emit("close",this.isShow) this.$watch("proptType","proptTypeWatch") }, // 弹框类型颜色 propt_type(){ if(this.proptType=="success"){ this.bgColor="rgba(7,193,96,0.2)"; }else if(this.proptType=="warning"){ this.bgColor="rgba(230,162,60,0.2)"; }else if(this.proptType=="error"){ this.bgColor="rgba(245,108,108,0.2)"; }else if(this.proptType=="info"){ this.bgColor="rgba(147,147,153,0.2)"; } if(this.proptType=="success"){ this.color="#07c160"; }else if(this.proptType=="warning"){ this.color="#e6a23c"; }else if(this.proptType=="error"){ this.color="#f56c6c"; }else if(this.proptType=="info"){ this.color="#909399"; } this.tColor=this.color; this.tBgColor=this.bgColor; }, // 关闭弹窗 close(){ this.isMessage=false; this.isDialog=false; this.isShow=false; this.$emit("close",this.isShow) }, // 自动关闭 autoClose(){ if(this.time>0){ if(this.isShow==true || this.isMessage==true || this.isDialog==true){ this.timer=setTimeout(()=>{ this.isFlag=false; this.close(); clearTimeout(this.timer); },this.time); } } }, // 设置弹窗宽度,对齐方式 setWidth(){ if(this.type=="alert"){ if(this.phoneInfo){ this.width=this.phoneInfo.width-20; } this.height=null; this.iconWidth=25; this.iconHeight=25; this.isClose=true; this.direction="row"; this.justifyContent="flex-start"; } else if(this.type=="message"){ this.width=null; this.height=null; this.iconWidth=25; this.iconHeight=25; this.isClose=false; this.direction="row"; this.justifyContent="flex-start"; }else if(this.type=="toast"){ this.width=150; this.height=150; this.iconWidth=60; this.iconHeight=60; this.direction="column"; this.justifyContent="center"; this.isClose=false; } }, // 弹窗位置 offsetInit(){ this.getPhoneInfo(); if(this.type=="message" || this.type=="alert" || this.type=="toast"){ var el=this.$element("messagesContent").getBoundingClientRect(); }else if(this.type=="dialog"){ var el=this.$element("dialogBox").getBoundingClientRect(); } let offsetLeft=(this.phoneInfo.width-el.width)/2; let offsetTop=this.offsetTop; if(this.phoneInfo){ this.offsetLeft=offsetLeft; } if(offsetTop=="center"){ this.offsetTop=(this.phoneInfo.height-el.height)/2 } }, confirm(){ this.isFlag=false; this.isDialog=false; this.isShow=false; this.$emit("confirm",this.isShow); }, cancel(){ this.isFlag=false; this.isDialog=false; this.isShow=false; this.$emit("cancel",this.isShow); }, // 获取设备信息 getPhoneInfo(){ let that=this; device.getInfo({ success: function(data) { that.phoneInfo=data; that.phoneInfo["width"]=data.windowWidth/data.screenDensity; that.phoneInfo["height"]=data.windowHeight/data.screenDensity; } }); }, isShowWatch(newV,oldV){ this.isShow=newV; this.type_init(); }, proptTypeWatch(newV,oldV){ this.proptType=newV; this.propt_type(); }, typeWatch(newV,oldV){ this.type=newV; this.setWidth(); setTimeout(()=>{ this.offsetInit(); },50); }, colorWatch(newV,oldV){ this.tColor=newV; }, bgColorWatch(newV,oldV){ this.tBgColor=newV; }, } ``` ## 父组件调用方式 - 代码 ```html
``` - 父组件调用子组件的验证方法 ```js data: { isShow:true, proptType:"success", color:"", bgColor:"", type:"message", icon:"/common/icon/success.png", }, btn(option,type){ console.info("type:"+type) this.isShow=!this.isShow; this.proptType=option; this.type=type; if(option=="success"){ this.icon="/common/icon/success.png" }else if(option=="warning"){ this.icon="/common/icon/warning.png" }else if(option=="info"){ this.icon="/common/icon/info.png" }else if(option=="error"){ this.color="#955620"; this.icon="/common/icon/error.png" } }, close(e){; this.isShow=e.detail; }, confirm(e){ console.info("确认:"+JSON.stringify(e)); this.isShow=e.detail; }, cancel(e){ console.info("取消:"+JSON.stringify(e)) this.isShow=e.detail; } ``` - 参数使用说明 **time:** {default: 1500};自动关闭时长. **isShow:** {default: false}, 默认是否显示 **type:** {default:"message"}, 弹框类型:message消息提示框;alert警告框;toast请提示 ;dialog弹出框 **text:**{default:"信息内容"},提示内容信息 **proptType:**{default:"success"},提示类型,可取值 success,warning,error,info **bgColor:**{default:""}, 背景色 **color:**{default:""}, 文字颜色 **offsetTop:**{default:0},弹窗距离顶部位置,如果传递center,会垂直水平居中 **icon:**{default:""}, 小图标 **isClose**:{default:false},是否显示关闭按钮 **confirmBtn:**{default:"确认"},确定按钮文本内容 **cancelBtn:**{default:"取消"}, 取消按钮文本内容 **@close:** 关闭按钮回调事件 **@confirm:** 确定按钮回调事件 **@cancel:** 取消按钮回调事件 #### Tips 1. isClose属性在type=dialo或者alert有效。 2. confirmBtn,cancelBtn,confirm,cancel 在type=dialog有效 3. icon 在type=dialog无效 ## 结语 原文demo在 https://gitee.com/queling/propt,感谢您的每一次耐心阅读。