找回密码
 会员注册
查看: 11|回复: 0

基于Taro的微信小程序填坑指南(bei)_UTF_8

[复制链接]

2万

主题

0

回帖

7万

积分

超级版主

积分
74108
发表于 2024-9-30 21:08:57 | 显示全部楼层 |阅读模式
前言最近在基于 Taro.js 开发微信小程序。由于小程序与 web 存在很大差异,踩了很多坑。架构小程序实质就是 hybrid,但是是受限的。js 运行在逻辑层,是一个没有 html 的单纯的 js 解释器,只能通过 API 和视图层、Native 层交互。逻辑层和视图层是两个独立的线程,完全隔离。对于平台方而言,这种设计极大增加了平台对应用的控制,也减少了各种风险。但是对于开发者而言,很多 h5 的能力在小程序中被阉割甚至不被提供,开发小程序相当于戴着镣铐跳舞。性能小程序的性能可以类比 React Native,每次交互都需要通过 native 的 bridge 进行,差于 native 和 h5。正文方案:三态抽屉拖动切换实现需求:实现一个抽屉浮层,状态1:高度为屏幕高度的一半状态2:占满屏幕状态3:关闭通过拖动在三个状态之间切换方案与问题:touch 方案方案:通过 onTouchStart/onTouchMove/onTouchEnd/onTouchCancel 捕捉触摸事件;onTouchEnd 时判断状态缺陷:频繁 setState,onTouchMove 时页面有卡顿scroll 方案方案:使用 scrollview,绑定 onScroll 事件;动画效果为 scroll 效果;onScrollEnd 时判断状态缺陷:惯性滑动时,scrollend 事件是手势停止时触发,并非惯性滑动结束时触发,导致无法获取准确的滚动位置(不能接受)微信小程序 wxs 响应事件 https://developers.weixin.qq.com/miniprogram/dev/framework/view/interactive-animation.htmlTaro.js 暂不支持,可考虑 Taro 混合小程序原生组件使用方案:多页左右滑动切换实现方案:小程序 Swiper 组件方案方案:使用小程序的 swiper,绑定 chang 事件,设置数据量为所有的页数,但只有三页有数据:前一页/当前页/下一页;翻页时切换当前页,并设置三页数据/清除其他页数据效果:切换效果流畅;多页渲染性能可以接受方案:定制导航栏实现方案:通过设置 navigationStyle: "custom" 不显示官方导航栏项目入口 app.ts 获取状态栏和胶囊按钮的布局信息,计算得到导航栏需要的布局数据自定义导航栏组件,通过 getCurrentPages 获取路由信息,判断左侧按钮类型-返回/首页/无问题:现象:首页在页面跳转后返回,多出返回按钮原因:页面跳转时进行了 setState 导致 re-render,然后组件获取到跳转后的路由信息进行渲染解决:对按钮状态使用 useMemo,使用第一次 render 时的缓存注意事项:webview 无效:客户端 6.7.2 版本开始,navigationStyle: custom 对 web-view 组件无效(详见https://developers.weixin.qq.com/miniprogram/dev/component/web-view.html)问题:页面卸载后异步工作仍然会运行该问题类似于 web 的 SPA 应用,在从当前页面 A 返回到上一页面后,A 页面的异步工作仍然会运行。解决方法:页面卸载时清除异步操作页面卸载时设置标记变量,异步回调运行时判断标记变量再进行操作问题:获取页面dom节点的时机区别于在 web react 环境下第一次 useEffect 能获取到 dom 节点,在第一次 useEffect/useDidShow中,小程序的页面 dom 节点尚未挂载,获取不到。onLoad -> onShow -> useEffect -> onReady解决方法:setTimeOut 推迟一段时间并轮询wx.nextTick 并轮询直到获取到onReady/useReady问题:路由跳转之后(异步)无法获取页面dom节点路由跳转后,异步的 SelectorQuery.exec 等方法的回调不会执行,比如 react 生命周期/定时器/Promise等情况例子如下Taro.navigateTo({url:'/',});setTimeOut(()=>{constquery=Taro.createSelectorQuery();query.select('#a').fields({node:true}).exec((res)=>{console.log(res[0].node);});},0);解决方法:在路由跳转时同步调用 SelectorQuerysetTimeOut 推迟路由跳转onShow 时再处理问题:小程序环境缺少很多全局方法,如 atob/btoa 等等解决方法:手写第三方Polyfill问题:Taro.js 中使用 require('crypto') 会打包 size 很大的 polyfill因为 webpack 打包时,遇到 require('crypto'),会引入对应的 polyfill ,导致包 size 大大增加情景介绍:开发小程序时,打包的 size 很大,分析发现是打包了很多 polyfill,如 bn.js。追踪依赖链,bn.js -> browserify-sign -> crypto-browserify -> node-libs-browser,node-libs-browser 包提供了某些 Node 库供浏览器使用,可能是 crypto 的浏览器环境的 polyfill。全局搜索,发现使用的公司的图片上传组件中使用了 require('crypto'),并且实质上与 crypto 相关的方法并没有实际调用。移除 require('crypto') 后,size 减少了 600 KB。解决方法:尽量避免使用 require('crypto')使用替代的第三方库问题:微信小程序中使用 InnerAudioContext 播放音频,onTimeUpdate 有时不触发在使用 InnerAudioContext 播放音频时,当进行调整播放进度(seek)/重新播放等操作后,onTimeUpdate 不会触发。原因分析音频加载导致 onUpdateTime 失效(比如调用 seek 的时候,触发了音频自动加载)解决方法:访问 innerAudioContext.paused 可以使 onUpdateTime 生效,而音频加载完成会触发 onCanPlay,所以在 onCanPlay 回调中访问即可audioManager.onCanplay(()=>{audioManager.paused;});小程序音频播放:Audio:不再维护,功能较少InnerAudioContext:普通音频播放BackgroundAudioManager:背景音频,全局唯一WebAudioContext:Beta中,类似于 Web_Audio_APIMediaAudioPlayer:用于播放视频解码器 VideoDecoder 输出的音频InnerAudioContext 与 BackgroundAudioManager 的区别:InnerAudioContext 是普通的音频播放,可以有多个实例播放多个音频;BackgroundAudioManager 全局唯一,只能同时播放一个音频InnerAudioContext 在小程序进入后台的时候会被暂停,BackgroundAudioManager 会在手机状态栏有音乐播放组件,微信内有悬窗,在小程序进入后台时依旧会播放BackgroundAudioManager 必须填写,可填封面、专辑名、歌手等信息问题:微信小程序中 scroll-view 的滚动问题使用自适应方案无法滚动,必须设置 height 才能在垂直方向滚动当 scroll-view 组件的第一个直接子孙元素设置了 margin-top 时,即使 scroll-view 只有一行也可以滚动。解决方案:使用 padding-top /添加带高度的空白元素问题:谨慎使用 canvas在微信中,对于 canvas 的支持存在很多问题,目前已知的问题有:OffScreenCanvas 的版本支持和文档不符合Canvas.createImage 创建的图片,在 IOS 中,onload 事件不会触发方案:图片裁剪的方法给定了一张原图和四边形坐标,裁剪出四边形所框选出的区域作为独立的图片。最开始的做法是通过小程序的 Canvas 实现,但是微信小程序对于 Canvas 的支持存在问题,因此采用一种折中的方案完成。通过四边形坐标,计算出四边形的外接矩形通过 background-image 、background-position 和 background-size 定位裁剪的图片区域限制元素的尺寸为外界矩形这种方案有两个需要注意的点:裁剪结果是矩形而不是四边形需要计算容器尺寸,适配最大宽度点击阅读原文,了解更多技术干货~
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-14 04:09 , Processed in 0.801085 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表