记录篇(2)---- uniapp在项目中的实际问题
项目也总算正式上线了,终于有时间来记录这段时间在项目中的一些问题和不足了。
1.onLoad和onShow
onLoad: 页面加载的时候触发,只触发一次,从二级页面回来时不会触发。
onShow:页面显示的时候触发,只要进入或返回该页面就会触发,从二级页面回来也会触发。
例子:
第一次进入A页面,会依次触发onLoad和onShow方法,再进入B页面,从B页面返回到A页面时会触发onShow方法。
onSHow方法用来刷新页面比较合适,onLoad方法适合用在初始化加载数据时。
onLoad在onShow之前触发。
2.安卓应用加载网络图片,解决缓存不能正常更新图片的问题
图片是从服务器获取直接放在页面加载的,所以当页面加载之后图片也加载完成,但由于安卓应用会自动缓存加载过得图片,当服务器修改过同名的图片时,APP中并不会显示新的图片。这个问题一直困扰良久,后来想到一个方法就是直接给网络图片加一个时间戳,一秒更新一次,这样的话就不会出现缓存不显示正确图片的情况了,但这样做会导致另外的问题就是当网络不好或断网的情况下,图片不能显示…大家如果有更好的方法的话欢迎分享哟~
let now = new Date();// 创建时间戳 (由于计算出的是毫秒为单位的时间戳,请求时间过快,并不符合实际需求,所以转换为秒的时间戳就行)
let time = now.getTime()/1000;
let img = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1575437545598&di=04d0f1f2dc5165ff441b66b0f6a38423&imgtype=0&src=http%3A%2F%2Fwx3.sinaimg.cn%2Forj360%2F005ZWRGigy1g7moazx0hnj30dw08qwfb.jpg?t=' + time
3.setInterval()和setTimeout()的区别
setInterval()和setTimeout()常被用来处理延时和定时任务。
setTimeout:用于在指定的毫秒数后调用函数或计算表达式。
setInterval:在每隔指定的毫秒数循环调用函数或表达式,直到clearInterval清除该定时器。
表达式:
setTimeout(()=>{// 逻辑代码
},1000)setInterval(()=>{// 逻辑代码
},1000)
注:若只是想做延迟执行某方法或功能的话,建议使用setTimeout,尽量少使用setInterval。
可使用setInterval刷新表单,对于一些表单的假实时指定时间刷新同步。
如:
let timer = setInterval(() => {// 根据flag来判断是否暂定定时器if(this.flag) {// 从后台获取数据,更新数据uni.resquest({url: "",method: "",header: {},success: (res) => {this.data = res.data},fail: (err) => {console.log("请求失败:"+err)}})} else {// 使用clearInterval来结束该定时器clearInterval(timer) }
}, 8000)
(每8秒执行一次任务,当this.flag为false是清除该定时器的任务)
以上是举的简单例子用来刷新后台给的数据,并没有判断状态码,也没有做性能优化方面的处理,请勿在项目中直接这样使用。
setInterval的弊端
(1)无视代码错误
对调用的代码是否报错并不会有其他提示,即使调用的代码由于某种原因出错,它还是会在没有碰到clearInterval的情况下
持续不断的调用该代码。
(2)无视网络延迟
由于某些原因(服务器过载、临时断网、流量剧增、用户带宽受限,等等),请求的实际时间会增加,但setInterval仍然
会按定时持续不断地触发请求,最终导致客户端网络队列会被塞满。
4.Math对象常用方法
// 1.只保留整数部分(丢弃小数部分)
parseInt(5.1234);// 5
// 2.向下取整(<= 该数值的最大整数)和parseInt()一样
Math.floor(5.1234);// 5
// 3.向上取整(有小数,整数就+1)
Math.ceil(5.1234);// 4.四舍五入(小数部分)
Math.round(5.1234);// 5
Math.round(5.6789);// 6
// 5.绝对值
Math.abs(-1);// 1
// 6.返回两者中的较大值
Math.max(1,2);// 2
// 7.返回两者中的较小值
Math.min(1,2);// 1
// 8.随机数(0-1)
Math.random();// 解析字符串 返回浮点数 若不是数字 则返回NaN
parseFloat('5.1234'); // 5.1234
5.Date对象
Date对象具体的属性和方法请查看官方文档:点击此处查看官方文档
例子:获取当前时间的下周二14:00,若不足一天则使用倒计时,否则倒计天数。
// 使用面向对象 比直接使用时间戳要简单的多
getEndTime(globalCurrentDate) {// globalCurrentDate 是当前时间var now = new Date(globalCurrentDate);var nowTime = now.getTime(); // 获取当前时间戳this.currentTime = nowTime; var endDate = new Date(); // 创建当前时间对象var day = now.getDay(); // 获取今天是周几var oneDayTime = 24 * 60 * 60 * 1000; // 一天的时间// 周天if (day == 0) {day = 7;}// 周一 获取结束对象if (day == 1) {// 周一的结束对象为当前时间(周一)+一天的时间endDate.setTime(nowTime + oneDayTime);} else if (day == 2) { // 周二 获取结束对象// 周二的结束对象就是当前时间endDate.setTime(nowTime); // 判断结束时间戳是否小于当前时间 若当前时大于结束时间 则为下个周二if (endDate.getTime() < nowTime) {endDate.setTime(nowTime + (9 - day) * oneDayTime);}} else if (day >= 3) { // 周三到周天则为正常的倒计天数 获取下周二的对象// 当前时间+ (9 - day) * 一天时间endDate.setTime(nowTime + (9 - day) * oneDayTime);}endDate.setHours(14, 0, 0, 0); // 下周二的结束时间let endTime = this.dateFormat(endDate, 'yyyy年MM月dd日'); // 将结束对象转为日期this.lastTime = endTime.split('年')[1]; // 周二的日期let days = (endDate.getTime() - nowTime) / oneDayTime; // 剩余天数if (days >= 1) {this.retaminDays = Math.ceil(days); // 向上取整获取剩余天数} else {this.continueTime((endDate.getTime() - nowTime) / 1000); // 24小时倒计时}
},
// 倒计时
continueTime(params) {// 根据params倒计时let timer = setInterval(() => {if (params > 0) {this.currentTime++; //根据当前时间++params--;this.retaminDays = this.secToTime(params);} else {// 时间结束this.retaminDays = '00:00:00';}}, 1000);
},
// 将秒转为 时:分:秒
secToTime(time) {let t = '';if (time >= 0) {let hour = Math.floor(time / 60 / 60) % 60;let min = Math.floor(time / 60) % 60;let sec = time % 60;if (hour < 10) {t = '0';}t += hour + ':';if (min < 10) {t += '0';}t += min + ':';if (sec < 10) {t += '0';}t += sec;}return t;
},
// 获取截止日期
dateFormat(time, format) {var t = new Date(time);var tf = function(i) {return (i < 10 ? '0' : '') + i;};return format.replace(/yyyy|MM|dd|HH|mm|ss/g, function(a) {switch (a) {case 'yyyy':return tf(t.getFullYear());break;case 'MM':return tf(t.getMonth() + 1);break;case 'mm':return tf(t.getMinutes());break;case 'dd':return tf(t.getDate());break;case 'HH':return tf(t.getHours());break;case 'ss':return tf(t.getSeconds());break;}});
}
以上方法还可以简单一些,但是由于本人对时间实在掌握的不是很好,所以只能做到这里了。各位有意见可以提哦~~
6.eval()和JSON.parse() JSON.stringify()
(1)eval()
W3C中对eval()函数的解释是:可计算某个字符串,并执行其中的JavaScript代码。
示例:
eval("x=10;y=20;document.write(x*y)") // 200
document.write(eval("2+2")) // 4
var x=10
document.write(eval(x+17)) // 27
eval()还可以用来解析json
示例:
var data = "{a: '1',b: '2'}"
var obj = eval("("+data+")") // 转换为json
console.log(obj) // {a:'1',b:'2'}此处将data用()括起来是由于json是以”{}”的方式来开始以及结束的,在JS中,它会被当成一个语句块来处理,所以必须
强制性的将它转换成一种表达式。加上圆括号的目的是迫使eval函数在处理JavaScript代码的时候强制将括号内的表达式(expression)转化为对象,而不是作为语 句(statement)来执行。举一个例子,例如对象字面量{},如若不加外层的括号,那么eval会将大括号识别为JavaScript代码块的开始 和结束标记,那么{}将会被认为是执行了一句空语句。看下面两个例子:console.log(eval("{}"); // return undefined console.log(eval("({})");// return object[Object]
注:虽然 eval() 的功能非常强大,但在实际使用中用到它的情况并不多。
(2)JSON.parse() 和JSON.stringify()
前者是将格式完好的json字符串转为json对象,所谓“格式完好”,就是要求json字符串必须严格符合JSON格式,属性名和
属性值必须用双引号,单引号只能用在{}外。
后者是将json对象转为字符串,在获取后台返回的数据时,经常会使json对象的格式,若直接打印此对象会出现
object Object,所以此时只需要使用JSON.stringify()转换一下即可看出json对象的数据。
示例:
var jsonStr = '{"a":"1","b":"2"}';
var obj = {a:"1",b:"2"};
console.log(JSON.parse(jsonStr)) // {"a":"1","b":"2"}
console.log(JSON.stringify(obj)) // {"a":"1","b":"2"}(此类型为string)注:若jsonStr中有单引号导致JSON格式不对时,可将单引号转为双引号即可:
'{'a':'1','b':'2'}'.replace(/\'/g,'"')
7.检测升级
APP升级是一个很有必要的功能,在本次项目中升级的思路是:
① 首先检测后台的版本号与当前项目的版本号是否相同,如果相同则不升级,反之提示升级。
② 如果需要强制升级的话,则会将所有用户的状态清除,即使用户此时还在APP中,也会被强制退出提示升级。
升级代码演示:
checkVersionClick() {var that = thisuni.request({method:'GET',url:'http:/xxx.xxx/getVersion/',header: {'Content-Type': 'application/json',"Accept":"application/json",},success: (data) => {if(data.statusCode === 200){let version1 = plus.runtime.versionlet version2 = eval('(' + data.data[0].description + ')').versionNumif( version1 != version2){if(eval('(' + data.data[0].description + ')').isForceUpdate == 1){uni.showModal({ //提醒用户更新title: "更新"+eval('(' + data.data[0].description + ')').versionNum+'提示',confirmText:'立即升级',cancelText:'退出APP',showCancel:true,content: eval("(" + data.data[0].description + ")").description,success: (res) => {if (res.confirm) {that.isOnshowcheckVersion = trueplus.runtime.openURL(eval('(' + data.data[0].description + ')').pkgUrl);// plus.runtime.restart();//下载后重启app}else if(res.cancel){uni.showModal({ title: '退出应用提示', content: '是否退出大鲸智能?', success: function(res) { if (res.confirm) { // 退出当前应用,改方法只在App中生效 plus.runtime.quit();}else{ that.checkVersionClick()that.isOnshowcheckVersion = true} } }); }}})}}}}
})
},
升级设计的一些功能均是使用plus 5+ 的api做的点击此处查看官网。
5+的api用的不是很多,但是功能还是很强大的,有时间也需要多去研究研究哇。
8.uniapp打包
uniapp打包分为离线打包和在线打包。
离线打包即是使用Android studio以及官方SDK来进行打包,过程较为繁琐,有兴趣的同学可自行尝试点击此处查看详细过程。
在线打包也叫云打包,过程简单,方便,推荐使用,具体过程如下:点击查看文档
① 安装JRE环境,自行百度查看安装过程② 生成签名证书:进入cmd后输入
keytool -genkey -alias testalias -keyalg RSA -keysize 2048 -validity 36500 -keystore test.keystore
(testalias是证书别名,可修改为自己想设置的字符,建议使用英文字母和数字;test.keystore是证书文件名称,可修改为自己想设置的文件名称)
回车后输入需要填写的内容即可生成证书,记住此证书的路径。③ 查看证书:keytool -list -v -keystore test.keystore
输入密码后可看到证书的内容,此证书的MD5的指纹信息即为申请Andorid应用的应用签名,这两者必须匹配,否则上线可能会失败。④ 在hx中点击发行-->原生APP-云打包-->填写包名,选择使用自有证书(此处的证书即为刚刚生成的证书),填写证书别名、私钥密码和文件路径。
渠道包是用于对应APP上线的应用商店,需要上线哪个应用商店就选择对应的渠道包。
若只是测试第三方SDK只需要点击自定义基座就可以了。
注:微信支付必须使用自定义基座,打包后才可以测试!!!
好哒~今天的总结先到这里了,之后有新的问题再更新啦,欢迎各位小可爱的留言哦!
记录篇(2)---- uniapp在项目中的实际问题相关推荐
- 记录篇,自己在项目中使用过的。
图片选择器,6.0已经适配过,类似qq空间上传 点击打开链接_胡小牧记录 下面是效果图: PictureSelector PhotoPicker 类似qq空间发布心情. 点击打开链接 BubbleSe ...
- 记录一次在JavaWeb项目中,运行tomcat的时候,遇到XX程序包不存在的一系列排查问题。
记录一次在JavaWeb项目中,运行tomcat的时候,遇到XX程序包不存在的一系列排查问题. idea2020.1 maven版本3.3.9 tomcat版本8.5.31 第一次遇到的问题 程序包不 ...
- android+腾讯地图h5,在uniapp H5项目中使用腾讯地图sdk
这里主要针对的是H5,小程序或app都有现成的sdk可以使用: 本人是用uniapp在做微信公众号的h5页面,其中需要把经纬度信息转化成文字描述的位置信息,在腾讯地图开发平台上申请了一个key,然后下 ...
- 【BUG记录】Idea spring boot项目中target中没有同步更新最新目录文件及资源
BUG 日志 可见是bean创建异常,依赖注入失败 org.springframework.beans.factory.BeanCreationException: Error creating be ...
- uniApp H5项目中的压缩图片
子组件:选择相册还是拍照 并对相片进行压缩 成功之后把路径通过sFn方法传给父级,父级通过fFN方法走借口,对头像进行修改 <view class="main">< ...
- java 定时任务怎么关闭_浅谈springboot项目中定时任务如何优雅退出
在一个springboot项目中需要跑定时任务处理批数据时,突然有个Kill命令或者一个Ctrl+C的命令,此时我们需要当批数据处理完毕后才允许定时任务关闭,也就是当定时任务结束时才允许Kill命令生 ...
- 如何在Vue项目中使用vw实现移动端适配(转)
有关于移动端的适配布局一直以来都是众说纷纭,对应的解决方案也是有很多种.在<使用Flexible实现手淘H5页面的终端适配>提出了Flexible的布局方案,随着viewport单位越来越 ...
- 在iview项目中添加echarts3
写在前面 在即将结束的iview项目中,用到了大量的echarts3内容,简要记录下,在iview项目中,如何加载使用echarts3,并使其能够自适应页面大小. 开始 页面模板中添加带 id 的 d ...
- Webpack项目中引入Bootstrap4.x
Bootstrap是一个简洁.直观.强悍的前端开发框架,在Web开发中使用频率很高,本文主要记录一下如何在 webpack项目中引入Bootstrap4.x. 由于Bootstrap在各个Vue组件中 ...
最新文章
- zabbix监控客户端(二)
- 前端二十七:四彩边框
- Python机器学习Numpy, Scipy, Pandas, Scikit-learn, Matplotlib, Keras, NN速查手册
- 求矩阵中各列数字的和
- java商城项目中多线程执行_java多线程中执行多个程序的实例分析
- 打印zigzag矩阵
- ssis 计划任务_SSIS FTP任务概述
- QT_TableWidget插入checkbox
- Html5简单描述(优点与缺点)
- 畅捷通服务器系统,畅捷通
- 允许用户把若干个作业提交给计算机,允许多个用户将若干个作业提交给计算机系统集中处理的操作系统称为( )。...
- 采用中断模式编程并使用杜邦线模拟开关实现LED灯的亮灭
- lempel ziv matlab,1.9 Lempel-Ziv算法
- 徒手攀登酋长岩,世界第一人!
- 第九届蓝桥杯JavaB组省赛真题
- 英文会议论文出版地信息汇总
- android DevAppsDirect开源项目
- 付源泉老师 企业人才管理专家
- SEO 站长常用工具
- 用友U9,U9C学习资料