- wx.navigateBack场景问题,不知道有没有相同场景的同学,想借鉴一下?
目前的场景是,我再A页面跳转B页面,B页面会有params,然后B页面跳转C页面,C页面有输入等一系列操作,点击确认后请求会返回一个新的 id,我需要用这个新的 id在返回到B页面,B页面再用params上的参数去做请求, A跳B和C跳B的params是不同的。这个时候,使用 navigateTo的话,会返回到C页面(操作页面,肯定不对),用redirectTo,路由里就会有两个B页面,用户需要返回两次才能回到A页面,这个肯定也不太好,想知道有什么好的方法吗?C跳到B,B返回操作直接到A,目前我用了很hack的方式,就是先调用一下 navigateBack,然后再调用redirectTo,这样是可以实现的,但是会有一个跳转闪烁的问题,对用户不太友好,想问下还有什么好的解决办法吗?我没想到的,(或者navigateBack可以修改参数吗?这个可能有点难)
2023-07-19 - touch事件手指离开屏幕事件不会立即停止
请问下,我自己写一组兼听手势滑动事件,但是我在手指离开屏幕后,图片还一直在滑动,这是什么情况? 我全局设置了个变量g_start=false; touchStart中设置g_start=true; touchMove中判断 if(!g_start) return; 我用的是animation API接口操控图片动画的。 touchEnd中设置g_start=false; 但是并没有起作用。图片仍然一直在移动中,有什么解决办法? 1、如何解决手指移开后图片立刻停止移动 2、如何解决move移动卡顿情况
2018-05-28 - 小程序recorderManager.stop()发生延迟停止,求解?
<button class="talk_button" hidden="{{!keyboard}}" bindtouchstart="touchdown" bindtouchend="touchup">按住 说话button> // 按钮松开 touchup:function(){ const recorderManager = that.data.recorderManager; recorderManager.stop(); recorderManager.onStop((res) => { const { tempFilePath } = res that.data.filePath = res.tempFilePath; that.voiceToChar(); }) 按钮快速点击,然后释放,录音停止不了?touchup事件是没有问题的,录音启动录制也可以执行,就是stop事件在快速按住释放之后停止不了录音,而按住一段时间在释放就可以触发stop事件,这是为什么?求解?
2018-08-03 - 使用分页和空白view支撑解决Dom limit exceeded 问题
列表页数据量过大页面渲染节点过多会触发Dom limit exceeded . 解决方案如下。 欢迎讨论交流 [代码]// index.js[代码] [代码]Page({[代码][代码] [代码][代码]data: {[代码][代码] [代码][代码]currentPage: 0,[代码][代码] [代码][代码]pageFrame:[][代码][代码] [代码][代码]},[代码][代码] [代码][代码]pageSize: 10,[代码][代码] [代码][代码]currentPage:0,[代码][代码] [代码][代码]onLoad: [代码][代码]function[代码] [代码]() {[代码] [代码] //mock 一些数据[代码] [代码] [代码][代码]var[代码] [代码]list = [];[代码][代码] [代码][代码]for[代码] [代码]([代码][代码]var[代码] [代码]i = 0; i< 10000 ; i++) {[代码][代码] [代码][代码]list.push({[代码][代码] [代码][代码]name: [代码][代码]'ssss----'[代码] [代码]+ i,[代码][代码] [代码][代码]desc: [代码][代码]'aaaaa----'[代码] [代码]+ i,[代码][代码] [代码][代码]content: [代码][代码]'adasdadasdadadasdadadadadasdadad ----'[代码] [代码]+ i[代码][代码] [代码][代码]});[代码][代码] [代码][代码]}[代码] [代码] //数据分页[代码] [代码] [代码][代码]this[代码][代码].pagedList = [代码][代码]this[代码][代码].pageList(list);[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]listLength: list.length,[代码][代码] [代码][代码]list: [[代码][代码]this[代码][代码].pagedList[0]][代码][代码] [代码][代码]})[代码][代码] [代码][代码]},[代码] [代码] //滚动监听[代码] [代码] [代码][代码]onListScroll(e) {[代码][代码] [代码][代码]if[代码] [代码]([代码][代码]this[代码][代码].inPageUpdate) {[代码][代码] [代码][代码]return[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码][代码]var[代码] [代码]{ scrollTop } = e.detail;[代码][代码] [代码][代码]if[代码] [代码]([代码][代码]this[代码][代码].currentPage > 0) {[代码][代码] [代码][代码]var[代码] [代码]pageFrame = [代码][代码]this[代码][代码].data.pageFrame[[代码][代码]this[代码][代码].currentPage - 1];[代码][代码] [代码][代码]var[代码] [代码]screenHeight = wx.getSystemInfoSync().screenHeight;[代码][代码] [代码][代码]if[代码] [代码]((scrollTop + screenHeight) - (pageFrame.lastBottom + pageFrame.height) < -200) {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]true[代码][代码];[代码][代码] [代码][代码]this[代码][代码].currentPage -= 1;[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]currentPage: [代码][代码]this[代码][代码].currentPage,[代码][代码] [代码][代码]}, () => {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]false[代码][代码];[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码] [代码][代码]var[代码] [代码]currentPageFrame = [代码][代码]this[代码][代码].data.pageFrame[[代码][代码]this[代码][代码].currentPage];[代码][代码] [代码][代码]if[代码] [代码](currentPageFrame) {[代码][代码] [代码][代码]if[代码] [代码](scrollTop - (currentPageFrame.lastBottom + currentPageFrame.height) > 200) {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]true[代码][代码];[代码][代码] [代码][代码]this[代码][代码].currentPage += 1;[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]currentPage: [代码][代码]this[代码][代码].currentPage,[代码][代码] [代码][代码]}, () => {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]false[代码][代码];[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码][代码] [代码][代码]}[代码][代码] [代码][代码]},[代码] [代码] //计算分页高度[代码] [代码] [代码][代码]reachPageBottom() {[代码][代码] [代码][代码]if[代码] [代码]([代码][代码]this[代码][代码].inPageUpdate) {[代码][代码] [代码][代码]return[代码][代码];[代码][代码] [代码][代码]}[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]true[代码][代码];[代码][代码] [代码][代码]if[代码] [代码]([代码][代码]this[代码][代码].currentPage < [代码][代码]this[代码][代码].pagedList.length - 1) {[代码][代码] [代码][代码]var[代码] [代码]self = [代码][代码]this[代码][代码];[代码][代码] [代码][代码]var[代码] [代码]currentPage = [代码][代码]this[代码][代码].currentPage;[代码][代码] [代码][代码]wx.createSelectorQuery().select([代码][代码]'#listpage-'[代码] [代码]+ [代码][代码]this[代码][代码].currentPage).boundingClientRect([代码][代码]function[代码] [代码](rect) {[代码][代码] [代码][代码]if[代码] [代码](currentPage > 0) {[代码][代码] [代码][代码]rect.lastBottom = self.data.pageFrame[currentPage - 1].height + self.data.pageFrame[currentPage - 1].lastBottom[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]rect.lastBottom = 0;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]self.setData({[代码][代码] [代码][代码][`pageFrame[${currentPage}]`]: rect[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}).exec();[代码] [代码] [代码][代码]this[代码][代码].currentPage = [代码][代码]this[代码][代码].currentPage + 1;[代码][代码] [代码][代码]var[代码] [代码]nextPage = [代码][代码]this[代码][代码].pagedList[[代码][代码]this[代码][代码].currentPage];[代码][代码] [代码][代码]var[代码] [代码]key = `list[${[代码][代码]this[代码][代码].currentPage}]`[代码][代码] [代码][代码]var[代码] [代码]data = {};[代码][代码] [代码][代码]data[key] = nextPage;[代码][代码] [代码][代码]data.currentPage = [代码][代码]this[代码][代码].currentPage;[代码][代码] [代码][代码]console.log(data);[代码][代码] [代码][代码]this[代码][代码].setData(data, () => {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]false[代码][代码];[代码][代码] [代码][代码]});[代码][代码] [代码][代码]} [代码][代码]else[代码] [代码]{[代码][代码] [代码][代码]this[代码][代码].setData({[代码][代码] [代码][代码]pageEnd: [代码][代码]true[代码][代码],[代码][代码] [代码][代码]}, () => {[代码][代码] [代码][代码]this[代码][代码].inPageUpdate = [代码][代码]false[代码][代码];[代码][代码] [代码][代码]})[代码][代码] [代码][代码]}[代码] [代码] [代码][代码]},[代码][代码] [代码][代码]listItemTap(e) {[代码] [代码] //响应点击事件[代码] [代码] [代码] [代码] [代码][代码]console.log(e.currentTarget.dataset);[代码][代码] [代码][代码]},[代码] [代码] //分页函数[代码] [代码] [代码][代码]pageList(list) {[代码][代码] [代码][代码]var[代码] [代码]splitArray = (arr, len) => {[代码][代码] [代码][代码]var[代码] [代码]a_len = arr.length;[代码][代码] [代码][代码]var[代码] [代码]result = [];[代码][代码] [代码][代码]for[代码] [代码]([代码][代码]var[代码] [代码]i = 0; i < a_len; i += len) {[代码][代码] [代码][代码]result.push(arr.slice(i, i + len));[代码][代码] [代码][代码]}[代码][代码] [代码][代码]return[代码] [代码]result;[代码][代码] [代码][代码]}[代码][代码] [代码][代码]var[代码] [代码]pagedList = splitArray(list, [代码][代码]this[代码][代码].pageSize);[代码][代码] [代码][代码]return[代码] [代码]pagedList;[代码][代码] [代码][代码]}[代码] [代码]})[代码] [代码]/*index.wxss*/[代码][代码]page {[代码][代码] [代码][代码]height[代码][代码]: [代码][代码]100%[代码][代码];[代码][代码]}[代码] [代码].list {[代码][代码] [代码][代码]height[代码][代码]: [代码][代码]100%[代码][代码];[代码][代码] [代码][代码]width[代码][代码]: [代码][代码]100%[代码][代码];[代码][代码]}[代码] [代码].listitem {[代码][代码] [代码][代码]line-height[代码][代码]: [代码][代码]50[代码][代码]rpx;[代码][代码] [代码][代码]padding[代码][代码]: [代码][代码]20[代码][代码]rpx;[代码][代码] [代码][代码]font-size[代码][代码]: [代码][代码]32[代码][代码]rpx;[代码][代码] [代码][代码]color[代码][代码]: [代码][代码]#ff0000[代码][代码];[代码][代码] [代码][代码]border-bottom[代码][代码]: [代码][代码]1[代码][代码]rpx [代码][代码]solid[代码] [代码]#eeeeee[代码][代码];[代码][代码]}[代码] [代码].list-end{[代码][代码] [代码][代码]text-align[代码][代码]: [代码][代码]center[代码][代码];[代码][代码] [代码][代码]font-size[代码][代码]: [代码][代码]18[代码][代码]rpx;[代码][代码] [代码][代码]color[代码][代码]: [代码][代码]#b2b2b2[代码][代码];[代码][代码] [代码][代码]margin[代码][代码]: [代码][代码]15[代码][代码]rpx [代码][代码]0[代码] [代码]7.5[代码][代码]rpx;[代码][代码] [代码][代码]display[代码][代码]: flex;[代码][代码] [代码][代码]flex-[代码][代码]direction[代码][代码]: row;[代码][代码] [代码][代码]justify-[代码][代码]content[代码][代码]: [代码][代码]center[代码][代码];[代码][代码] [代码][代码]align-items: [代码][代码]center[代码][代码];[代码][代码]}[代码] [代码].list-end .line {[代码][代码] [代码][代码]width[代码][代码]: [代码][代码]20%[代码][代码];[代码][代码] [代码][代码]height[代码][代码]: [代码][代码]1px[代码][代码];[代码][代码] [代码][代码]background-color[代码][代码]: [代码][代码]#dddddd[代码][代码];[代码][代码] [代码][代码]margin[代码][代码]: [代码][代码]0[代码] [代码]30[代码][代码]rpx;[代码][代码]}[代码] [代码]<!-- index.wxml -->[代码][代码] [代码][代码]<[代码][代码]scroll-view[代码] [代码]class[代码][代码]=[代码][代码]"list"[代码] [代码]style[代码][代码]=[代码][代码]''[代码] [代码]scroll-y[代码][代码]=[代码][代码]"true"[代码] [代码]bindscrolltolower[代码][代码]=[代码][代码]"reachPageBottom"[代码] [代码]bindscrolltoupper[代码][代码]=[代码][代码]"reachPageTop"[代码] [代码]bindscroll[代码][代码]=[代码][代码]"onListScroll"[代码] [代码]enable-back-to-top[代码][代码]=[代码][代码]"true"[代码] [代码]upper-threshold[代码][代码]=[代码][代码]'100'[代码] [代码]lower-threshold[代码][代码]=[代码][代码]"100"[代码] [代码]scroll-top[代码][代码]=[代码][代码]"{{scrollTo}}"[代码][代码]>[代码] [代码] <!-- 循环分页 -->[代码] [代码] [代码][代码]<[代码][代码]view[代码] [代码]wx:for[代码][代码]=[代码][代码]"{{list}}"[代码] [代码]wx:for-item[代码][代码]=[代码][代码]"subList"[代码] [代码]wx:for-index[代码][代码]=[代码][代码]"page"[代码] [代码]id[代码][代码]=[代码][代码]"listpage-{{page}}"[代码] [代码]wx:key[代码][代码]=[代码][代码]"listpage"[代码] [代码]>[代码] [代码] [代码] [代码] <!-- 判断页面状态 -->[代码] [代码] [代码][代码]<[代码][代码]block[代码] [代码]wx:if="{{page - currentPage >= -1 && page - currentPage <= 1}}" >[代码] [代码] <!-- item渲染 -->[代码] [代码] [代码][代码]<[代码][代码]template[代码] [代码]is[代码][代码]=[代码][代码]"listitem"[代码] [代码]wx:for[代码][代码]=[代码][代码]"{{subList}}"[代码] [代码]data[代码][代码]=[代码][代码]"{{item:item, page,index}}"[代码] [代码]/>[代码][代码] [代码][代码]</[代码][代码]block[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]wx:else [代码][代码]style[代码][代码]=[代码][代码]'height:{{pageFrame[page].height}}px;'[代码] [代码]></[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]"list-end"[代码] [代码]wx:if="{{listLength > 0}}">[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'line'[代码][代码]></[代码][代码]view[代码][代码]>[代码][代码] [代码] [代码] [代码][代码]<[代码][代码]text[代码] [代码]wx:if[代码][代码]=[代码][代码]"{{pageEnd}}"[代码][代码]>以上共{{listLength || 0}}个数据</[代码][代码]text[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]button[代码] [代码]wx:else [代码][代码]loading[代码][代码]=[代码][代码]"true"[代码][代码] [代码][代码]disabled[代码][代码]=[代码][代码]"true"[代码] [代码]bindtap[代码][代码]=[代码][代码]"empty"[代码] [代码]class[代码][代码]=[代码][代码]"button-noborder"[代码] [代码]style[代码][代码]=[代码][代码]'font-size: 26rpx; background-color:transparent'[代码] [代码]>正在加载更多...</[代码][代码]button[代码][代码]> [代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'line'[代码][代码]></[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]scroll-view[代码][代码]>[代码] [代码] [代码][代码]<[代码][代码]template[代码] [代码]name[代码][代码]=[代码][代码]"listitem"[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码] [代码]class[代码][代码]=[代码][代码]'listitem'[代码] [代码]bindtap[代码][代码]=[代码][代码]'listItemTap'[代码] [代码]data-item[代码][代码]=[代码][代码]'{{item}}'[代码] [代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码][代码]>{{item.name}}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码][代码]>{{item.desc}}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]view[代码][代码]>{{item.content}}</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]<!-- 循环100个节点 -->[代码][代码] [代码][代码]<[代码][代码]text[代码][代码]>{{page}}--</[代码][代码]text[代码][代码]>[代码][代码] [代码][代码]<[代码][代码]text[代码] [代码]wx:for[代码][代码]=[代码][代码]"{{100}}"[代码] [代码]wx:for-index[代码][代码]=[代码][代码]'i'[代码] [代码]>{{index}}</[代码][代码]text[代码][代码]>[代码] [代码] [代码][代码]</[代码][代码]view[代码][代码]>[代码][代码] [代码][代码]</[代码][代码]template[代码][代码]>[代码] demo见代码片段 [代码]https:[代码][代码]//developers.weixin.qq.com/s/ItRHXsmg7L5r[代码]使用小程序开发工具导入片段可直接运行
2019-01-16 - 分包中的路径生成小程序码无效?
在生成小程序码时使用分包的路径无效
2022-08-15 - 微信小程序码获取-从频繁失败到成功率100%
早期实现方案 1. 方案实现 通过微信的appSecret获取小程序accessToken并缓存 微信小程序上很多操作都需要使用accessToken,比如用户授权手机号,当然也包括获取小程序码 通过微信提供的api获取到对应的小程序码,由于http接口直接返回的是图片本身,所以考虑将图片上传七牛服务器并获取图片链接,最后使用图片的链接来展示或保存小程序码 2. 方案优点 由于上传了小程序码,对于一些跳转固定页面和参数的码可以将图片链接存到数据库,以供用户下次分享使用,无需重复获取 3. 存在的问题 稳定性很差,获取小程序码的失败率比较高,甚至会出现一个时间段内完全获取不到码的情况 接口效率不好,由于每次都会存在图片上传,而且上传本身又比较耗时,导致服务器压力巨大且频繁出现慢接口,可能会影响到项目中的其他服务 改造后方案 1. 方案实现 获取小程序码后不再上传七牛,直接通过图片流的方式返回给前端 2. 方案优点 取消了图片的上传操作,接口效率大幅提升,提高了小程序码的获取成功率,也减轻了服务的压力 3. 存在的问题 依旧存在小程序码获取失败的情况 4. 问题排查 经排查日志发现是accessToken失效导致,缓存的accessToken失效时间远比微信规定的失效时间短,那究竟又是什么情况会导致accessToken失效呢?经讨论和实验发现以下三点: 我们微信的appSecret授权给第三方网站使用(比如阿拉丁),他们也有获取小程序码的服务,运营可以通过阿拉丁获取小程序码,这就会导致阿拉丁使用我们的appSecret获取accessToken,以至于我们缓存中的accessToken失效。 后端缓存中的accessToken存入和获取的逻辑存在缺陷,每当从缓存读取accessToken时,若缓存不命中,则通过微信api获取新的accessToken然后再存入缓存,这个逻辑容易导致缓存穿透,即当多个请求都没有命中缓存时,只有一个线程能通过微信api拿到新的accessToken,其他线程都拿不到。 当一个accessToken存在时间比较长时,手动调用微信api获取小程序码,会看到微信的api也会存在概率获取不到码的情况,但是一个全新生成的accessToken则不会有这种情况,至少在10分钟之内非常稳定。 最终的方案 1. 方案实现 通知运营不要再使用阿拉丁的生成小程序码的功能,若有这方面需求可以找技术帮忙获取。 缓存中的accessToken有效时间缩短至5分钟,保证每次使用的accessToken都能稳定获取小程序码。 修改accessToken的获取机制,由定时器来获取accessToken并更新缓存,定时器每4分钟执行一次,以确保每个请求都能命中缓存,若定时器出现异常,则回退之前的逻辑(请求没有命中缓存,通过微信api重新获取accessToken)。 最终效果 这一个方案上线后,线上再也没有出现小程序码没有获取成功的情况,观察日志也没再出现获取失败的情况,目前已经两周保持100%成功率了。 [图片]
2019-06-04 - 【小程序】setData有严重的性能问题?
如下图,WAService.js中的setData占用了大量时间 当列表数据量很大时,我做了回收处理,只渲染10条数据,进行数量加一操作时,一条数据进行setdata,set的数据量很少,但是还是有性能问题。 很迷茫啊,不知道怎么优化,有没有大佬指点一下 下图:searchGoods数据量少,20条时,同等操作 [图片] 下图::searchGoods数据量中,300条时,同等操作 [图片] 下图::searchGoods数据量中,1000条时,同等操作 [图片] 选择一张图,可以看到,一次操作,进行了三次setdata,数据量不大时,时间都有增长,第一个searchGoods的setdata时间增长最明显,但是searchGoods没有与视图直接绑定 1000条时,点击数量加1,三次setdata明细如下: 1.第一次setData的searchGoods传入了组件中,组件处理后,将裁剪的visibleData传入插槽,visibleData才真正与视图绑定 searchGoods的setdata花费了大量时间,这里我就不太明白 [图片] 20条数据,第一次setdata searchGoods时间: [图片] 1000条数据,第一次setdata searchGoods时间: [图片] 2.第二个setData,汇总数据和购物车,执行时间参考上面的图片 [图片] 3.第三个setData,searchGoods裁切后得到的visibleData,visibleData与视图绑定,执行时间参考上面的图片 [图片] 下面是 C方法: [图片] 下面是doUpdates方法: [图片]
2021-05-08