微信小程序-微信小程序外包-北京微信小程序外包

搜 索

Search:微信小程序


js详解微信小程序之提高应用速度小技巧js大全

WeTest 导读WeTest 导读WeTest 导读小程序科普类的文章已经很多了,今天这里讲的是针对小程序的优化方法,可以有效提高小程序的响应速度和用户体验。当然,开发体验也提高不少。1、提高页面加WeTest 导读WeTest 导读WeTest 导读小程序科普类的文章已经很多了,今天这里讲的是针对小程序的优化方法,可以有效提高小程序的响应速度和用户体验。当然,开发体验也提高不少。1、提高页面加载速度1、提高页面加载速度1、提高页面加载速度在小程序这个环境下,怎样提高页面加载速度呢? 这个问题很大,我把问题具体一下,如何缩短从用户点击某个链接,到打开新页面的这段时间? 这里抛一个核心关键点:从页面响应用户点击行为,开始跳转,到新页面onload事件触发,存在一个延迟,这个延迟大概在100-300ms之间(安卓响应比ios慢些)。从页面响应用户点击行为,开始跳转,到新页面onload事件触发,存在一个延迟,这个延迟大概在100-300ms之间(安卓响应比ios慢些)。这个延迟说短不短,我们可以利用这段时间,预先发起新页面所需要的网络请求。这样一来,就节省了100-300ms(或者一个网络请求的时间)。知道有这个gap后,代码如何实现呢?说白了,就是实现一个在A页面预加载B页面数据的功能。但而这种跨页面的调用,很容易把逻辑搞复杂,将不同页面的逻辑耦合在一起。所以,我们希望将预加载的逻辑隐藏于无形中,不增加任何的页面间耦合,以及开发复杂度。将预加载的逻辑隐藏于无形中下面以腾讯视频小程序为例,讲解下技术实现。下面以腾讯视频小程序为例,讲解下技术实现。小程序首页:小程序首页:当用户点击海报图后,会执行以下代码(就一行):接下来程序会加载播放页:播放页主要代码:可以看到,不管是外部页面的调用还是实际逻辑的实现都非常简洁。在第二个页面中,我们扩展了Page的生命周期函数,增加了onNavigate方法。该方法在页面即将被创建但还没开始创建的时候执行。老司机也许会发现这里有点蹊跷。在首页点击的时候,播放页根本就没有创建,对象都不存在,怎么访问到里面的方法呢?这里就要说下微信的页面机制。老司机也许会发现这里有点蹊跷。在首页点击的时候,播放页根本就没有创建,对象都不存在,怎么访问到里面的方法呢?这里就要说下微信的页面机制。在小程序启动时,会把所有调用Page()方法的object存在一个队列里(如下图)。每次页面访问的时候,微信会重新创建一个新的对象实例(实际上就是深拷贝)。也就是说,在A页面在执行点击响应事件的时候,B页面的实例还没创建,这时候调用的onNavigate方法,实际上是Page对象的原型(小程序启动时候创建的那个)。而接下来马上要被创建的B页面,又是另外一个object。所以,在onNavigate和onLoad方法中,this指针指的不是同一个对象,不能把临时数据存储在当前object身上。因此我们封装了一对全局的缓存方法,$put()和$take()。为了通用性,Page上用到的公共的方法,比如$route、$put、$take都定义在了一个Page的基类里面。基类还同时保存了所有页面的list,这样就可以做到根据页面名调用具体页面的onNavigate方法。 当然,并不是每个页面都需要实现onNavigate方法,对于没有定义onNavigate方法的,$route函数会跳过预加载环节,直接跳转页面。所以对于开发者来说,不需要关心别的页面实现了什么,对外看来完全透明。2、用户行为预测2、用户行为预测2、用户行为预测在上面的例子中,我们实现了用户主动点击页面,提前加载下一页面数据的方法。而在某些场景下,用户的行为可以预测,我们可以在用户还没点击的时候就预加载下个页面的数据。让下个页面秒开,进一步提升体验的流畅性。继续以腾讯视频小程序为例,主界面分为3个页卡(大部分小程序都会这么设计),通过简单的数据分析,发现进入首页的用户有50%会访问第二个页卡。所以预加载第二个页卡的数据可以很大程度提高用户下个点击页面的打开速度。同样,先看看代码实现。 首页预加载频道页的姿势:频道页的实现方法:跟第一个例子类似,这里定义了一个$preLoad()方法,同时给Page扩展了一个onPreload事件。页面调用$preLoad()后,基类会自动找到该页面对应的onPreload函数,通知页面执行预加载操作。 跟第一个例子不同,这里预加载的数据会保存在storage内,因为用户不一定会马上访问页面,而把数据存在全局变量会增加小程序占用的内存。微信会毫不犹豫的把内存占用过大的小程序给杀掉。也许对于大部分有app开发经验的同学来说,更普遍的做法是先让页面展示上次缓存的数据,再实时拉取新数据,然后刷新页面。这个方法在小程序上也许体验并不太好,原因是小程序的性能以及页面渲染速度都不如原生app。将一个大的data传输给UI层,是一个很重的操作。因此不建议采用这种方法。3、减少默认data的大小3、减少默认data的大小3、减少默认data的大小刚刚说到,页面打开一个新页面时微信会深拷贝一个page对象,因此,应该尽量减少默认data的大小,以及减少对象内的自定义属性。有图有真相:以一个100个属性的data对象为测试用例,在iphone6上,页面的创建时间会因此增加150ms。4、组件化方案4、组件化方案4、组件化方案微信没有提供小程序的组件化方案(相信一定在实现中)。但开谈不说组件化,写再多代码也枉然。这里演示一个简单的组件化实现。以腾讯视频播放页为例,页面定义如下:其中,P()函数是自定义的基类。这是一个非常有用的东西,可以把所有通用的逻辑都写在基类里面,包括pv统计,来源统计,扩展生命周期函数,实现组件化等。基类函数第一个参数是页面名称,作为页面的key。第二个是page对象,其中扩展了一个comps数组,里面就是所有要加载的组件。以播放器组件/comps/player/index.js为例:组件的定义跟一个普通Page对象一模一样,有data属性,onLoad、onShow等事件,也有页面响应的回调方法。wxml模板里定义的事件和js事件一一对应。基类做的事情,就是把这些组件对象的属性和方法复制到Page对象上(浅拷贝)。其中data属性会merge到一起。而微信预定义的生命周期函数(包括自己扩展的),则封装成队列按序执行。比如当系统调用onLoad方法时,实际上是执行了所有组件的onLoad方法,最后再执行Page的onLoad。以上是代码部分,至于wxml模板和wxss部分,就要手工import过去了。wxml:wxml:wxss:wxss:5、其他5、其他5、其他虽然小程序已经足够小巧,但启动速度还是有那么2-3秒,无法做到秒开。楼主尝试对小程序的启动时间做优化,但没有找到多少有价值的优化点。单个页面的初始化只需要1-2ms。也许大部分时间消耗在了微信跟服务器端通信的过程中。所幸,腾讯提供了一个可以自主进行服务器性能测试的环境,用户只需要填写域名和简单的几个参数就可以获知自己的服务器性能情况,目前在腾讯WeTest平台可以免费使用。以上就是本文的全部内容,希望对大家的学习有所帮助。
标签:

js微信小程序接入腾讯云验证码的方法步骤js大全

前言:最近做了一个小程序抽奖的活动,出现了部分用户恶意薅羊毛的现象,因此考虑接入腾讯云的验证码。其实腾讯的官方文档写的相当清晰:https://cloud.tencent.com/doc...前言:最近做了一个小程序抽奖的活动,出现了部分用户恶意薅羊毛的现象,因此考虑接入腾讯云的验证码。其实腾讯的官方文档写的相当清晰:https://cloud.tencent.com/doc... 不想啃文档的筒子们的就往下继续看吧~(虽然大同小异)整体效果整体效果整体效果1、小程序触发验证,跳转到验证码小程序2、在验证码小程序内通过验证,并携带参数跳回原来的小程序3、在原来的小程序内,监测携带回的参数,并作后续操作前提条件前提条件前提条件验证码接入前,需要先在验证码控制台中注册 AppID 和 AppSecret,注册完成后,您可以在控制台的基础配置中查看 AppID (下文extraData中使用) 以及 AppSecret。验证码控制台基础配置注意,这里的 appId 和 appSecret 和小程序后台的是不一致的!接入步骤接入步骤接入步骤1、在你需要的地方,唤起验证码小程序1、在你需要的地方,唤起验证码小程序首先在 app.json 配置 navigateToMiniProgramAppIdList,如下:{ "navigateToMiniProgramAppIdList": ["wx5a3a7366fd07e119"]}{ "navigateToMiniProgramAppIdList": ["wx5a3a7366fd07e119"]}这个appId是官方文档中直接提供的,搬上去就好。假设你的唤起方式是通过一个这样的按钮事件:验证验证toTCaptcha: function () {wx.navigateToMiniProgram({appId: 'wx5a3a7366fd07e119',path: '/pages/captcha/index',extraData: {appId: 'appId' //您申请的验证码的 appId}}) }toTCaptcha: function () {wx.navigateToMiniProgram({appId: 'wx5a3a7366fd07e119',path: '/pages/captcha/index',extraData: {appId: 'appId' //您申请的验证码的 appId}}) }2、在 app.js 获取验证结果2、在 app.js 获取验证结果2、在 app.js 获取验证结果由于小程序间相互跳转过程中产生的数据仅能在 app.js 中获取到,故需要在 app.js 的 onShow 中添加以下代码,来捕获验证结果 captchaResultApp({ // ... onShow: function(options) {// 解决各类回调的兼容问题if (!this.captchaTicketExpire) this.captchaTicketExpire = {};if (options.scene === 1038 && options.referrerInfo.appId === 'wx5a3a7366fd07e119') {const result = options.referrerInfo.extraData;if (result.ret === 0) {const ticket = result.ticket;if (!this.captchaTicketExpire[ticket]) {this.captchaResult = result;this.captchaTicketExpire[ticket] = true;}} else {// 用户关闭了验证码// 这里可以加上一些验证失败提示}} }, // ...});App({ // ... onShow: function(options) {// 解决各类回调的兼容问题if (!this.captchaTicketExpire) this.captchaTicketExpire = {};if (options.scene === 1038 && options.referrerInfo.appId === 'wx5a3a7366fd07e119') {const result = options.referrerInfo.extraData;if (result.ret === 0) {const ticket = result.ticket;if (!this.captchaTicketExpire[ticket]) {this.captchaResult = result;this.captchaTicketExpire[ticket] = true;}} else {// 用户关闭了验证码// 这里可以加上一些验证失败提示}} }, // ...});验证结果(captchaResult) 参数说明:3、将验证结果返回至服务端校验3、将验证结果返回至服务端校验3、将验证结果返回至服务端校验在小程序页面的 onShow 阶段,将验证结果及待提交的表单数据一起提交到服务器,进行校验。// page.jsconst app = getApp()Page({ data: {// ... }, onShow() {const captchaResult = app.captchaResult;app.captchaResult = null; // 验证码的票据为一次性票据,取完需要置空if (captchaResult && captchaResult.ret === 0) {// 将验证码的结果返回至服务端校验,以及后续的操作// const ticket = captchaResult.ticket;// const randstr = captchaResult.randstr;} }, // ...});// page.jsconst app = getApp()Page({ data: {// ... }, onShow() {const captchaResult = app.captchaResult;app.captchaResult = null; // 验证码的票据为一次性票据,取完需要置空if (captchaResult && captchaResult.ret === 0) {// 将验证码的结果返回至服务端校验,以及后续的操作// const ticket = captchaResult.ticket;// const randstr = captchaResult.randstr;} }, // ...});用一个词描述这个开发过程:搬上去!以上就是本文的全部内容,希望对大家的学习有所帮助。
标签:

js微信小程序服务器日期格式化问题js大全

"Mon Jan 06 2021 09:10:28 GMT+0800 (中国标准时间)""Mon Jan 06 2021 09:10:28 GMT+0800 (中国标准时间)"一般服务"Mon Jan 06 2021 09:10:28 GMT+0800 (中国标准时间)""Mon Jan 06 2021 09:10:28 GMT+0800 (中国标准时间)"一般服务器获取到的日期都是这样的,我们需要对其进行格式化在utils目录创建filter.wxs文件filter.wxs//日期格式化var formatTime = function (strDate, format = "yyyy-MM-dd hh:mm:ss") { // 解决ios出现NaN问题 var realDate = strDate ? getDate(strDate.replace(getRegExp('-', 'g'), '/')) : getDate(); var regYear = getRegExp("(y+)", "i"); var date = [["M+", realDate.getMonth() + 1],["d+", realDate.getDate()],["h+", realDate.getHours()],["m+", realDate.getMinutes()],["s+", realDate.getSeconds()],["q+", Math.floor((realDate.getMonth() + 3) / 3)],["S+", realDate.getMilliseconds()], ]; var reg1 = regYear.exec(format); if (reg1) {format = format.replace(reg1[1], (realDate.getFullYear() + '').substring(4 - reg1[1].length)); } for (var i = 0; i var reg2 = getRegExp("(" + date[i][0] + ")").exec(format);if (reg2) {format = format.replace(reg2[1], reg2[1].length == 1 ? v : ("00" + date[i][1]).substring(("" + date[i][1]).length));} } return format;}module.exports = { formatTime: formatTime,//日期格式化}//日期格式化var formatTime = function (strDate, format = "yyyy-MM-dd hh:mm:ss") { // 解决ios出现NaN问题 var realDate = strDate ? getDate(strDate.replace(getRegExp('-', 'g'), '/')) : getDate(); var regYear = getRegExp("(y+)", "i"); var date = [["M+", realDate.getMonth() + 1],["d+", realDate.getDate()],["h+", realDate.getHours()],["m+", realDate.getMinutes()],["s+", realDate.getSeconds()],["q+", Math.floor((realDate.getMonth() + 3) / 3)],["S+", realDate.getMilliseconds()], ]; var reg1 = regYear.exec(format); if (reg1) {format = format.replace(reg1[1], (realDate.getFullYear() + '').substring(4 - reg1[1].length)); } for (var i = 0; i var reg2 = getRegExp("(" + date[i][0] + ")").exec(format);if (reg2) {format = format.replace(reg2[1], reg2[1].length == 1 ? v : ("00" + date[i][1]).substring(("" + date[i][1]).length));} } return format;}module.exports = { formatTime: formatTime,//日期格式化}wxml创建时间:{{filter.formatTime(item.creatTime, 'yyyy-MM-dd hh:mm:ss')}}创建时间:{{filter.formatTime(item.creatTime, 'yyyy-MM-dd hh:mm:ss')}}渲染页面直接引用,并且进行日期格式化调用7
标签:

js微信小程序实现吸顶效果js大全

最开始的时候,在小程序中实现吸顶效果,开发工具看起来还挺好的,但是在真机上就会有问题了。 原因是我不停的去 setData 会导致操作反馈延迟严重,无法及时将操作处理结果及时传递到视图层。setDat最开始的时候,在小程序中实现吸顶效果,开发工具看起来还挺好的,但是在真机上就会有问题了。 原因是我不停的去 setData 会导致操作反馈延迟严重,无法及时将操作处理结果及时传递到视图层。setDatasetData后面就对代码进行了调整,避免不停的去setData效果图效果图吸顶前吸顶后代码部分代码部分wxml 新品推荐限时优惠火爆热搜猜你喜欢 新品推荐限时优惠火爆热搜猜你喜欢 wxssview, text { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}.navbar-wrap { width: 100%;}.navbar-wrap .column { width: 100%; height: 80rpx; display: flex; flex-direction: row; align-items: center; justify-content: space-around; background: #fff; border-bottom: solid 1px #eee; top: 0; left: 0; z-index: 100;}.navbar-wrap .column.fixed { position: fixed;}/* 以下的代码不重要 */.navbar-wrap .column .block { width: 25%; height: 80rpx; line-height: 80rpx; text-align: center; font-size: 30rpx; color: #333; letter-spacing: 1px; position: relative;}.navbar-wrap .column .block::after { content: ""; width: 60%; height: 3px; border-radius: 2px; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); background: transparent;}.navbar-wrap .column .block.active { color: #1490ce; font-weight: bold;}.navbar-wrap .column .block.active::after { background: linear-gradient(160deg, rgba(8, 220, 230, 0.7) 10%, rgba(0, 140, 255, 0.7) 90%);}view, text { box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;}.navbar-wrap { width: 100%;}.navbar-wrap .column { width: 100%; height: 80rpx; display: flex; flex-direction: row; align-items: center; justify-content: space-around; background: #fff; border-bottom: solid 1px #eee; top: 0; left: 0; z-index: 100;}.navbar-wrap .column.fixed { position: fixed;}/* 以下的代码不重要 */.navbar-wrap .column .block { width: 25%; height: 80rpx; line-height: 80rpx; text-align: center; font-size: 30rpx; color: #333; letter-spacing: 1px; position: relative;}.navbar-wrap .column .block::after { content: ""; width: 60%; height: 3px; border-radius: 2px; position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); background: transparent;}.navbar-wrap .column .block.active { color: #1490ce; font-weight: bold;}.navbar-wrap .column .block.active::after { background: linear-gradient(160deg, rgba(8, 220, 230, 0.7) 10%, rgba(0, 140, 255, 0.7) 90%);}jsPage({ data: {navbarInitTop: 0, //导航栏初始化距顶部的距离isFixedTop: false, //是否固定顶部 }, /*** 生命周期函数--监听页面加载*/ onLoad: function(options) { }, /*** 生命周期函数--监听页面显示*/ onShow: function() {var that = this;if (that.data.navbarInitTop == 0) {//获取节点距离顶部的距离wx.createSelectorQuery().select('#navbar').boundingClientRect(function(rect) {if (rect && rect.top > 0) {var navbarInitTop = parseInt(rect.top);that.setData({navbarInitTop: navbarInitTop});}}).exec();} }, /*** 监听页面滑动事件*/ onPageScroll: function(e) {var that = this;var scrollTop = parseInt(e.scrollTop); //滚动条距离顶部高度//判断'滚动条'滚动的距离 和 '元素在初始时'距顶部的距离进行判断var isSatisfy = scrollTop >= that.data.navbarInitTop ? true : false;//为了防止不停的setData, 这儿做了一个等式判断。 只有处于吸顶的临界值才会不相等if (that.data.isFixedTop === isSatisfy) {return false;}that.setData({isFixedTop: isSatisfy}); }})Page({ data: {navbarInitTop: 0, //导航栏初始化距顶部的距离isFixedTop: false, //是否固定顶部 }, /*** 生命周期函数--监听页面加载*/ onLoad: function(options) { }, /*** 生命周期函数--监听页面显示*/ onShow: function() {var that = this;if (that.data.navbarInitTop == 0) {//获取节点距离顶部的距离wx.createSelectorQuery().select('#navbar').boundingClientRect(function(rect) {if (rect && rect.top > 0) {var navbarInitTop = parseInt(rect.top);that.setData({navbarInitTop: navbarInitTop});}}).exec();} }, /*** 监听页面滑动事件*/ onPageScroll: function(e) {var that = this;var scrollTop = parseInt(e.scrollTop); //滚动条距离顶部高度//判断'滚动条'滚动的距离 和 '元素在初始时'距顶部的距离进行判断var isSatisfy = scrollTop >= that.data.navbarInitTop ? true : false;//为了防止不停的setData, 这儿做了一个等式判断。 只有处于吸顶的临界值才会不相等if (that.data.isFixedTop === isSatisfy) {return false;}that.setData({isFixedTop: isSatisfy}); }})以上就是本文的全部内容,希望对大家的学习有所帮助。
标签: