2023年11月28日发(作者:)
微信⼩程序开发总结与⼼得
0 前⾔
最近的⼯作重⼼⼀直在⼩程序,也开发了⼏个⼩程序,对⼩程序开发的流程及相关技术相对⽐较熟悉,在开发过程中也总结了⼀些⼼得经验、了解
⼀些⼩程序⽂档上没有的东西、踩了⼀些坑。所以想着写篇⽂章记录下来,并借此将⼩程序开发的相关知识进⾏梳理,⽅便以后参考,也作为⾃⼰
⼯作的阶段性总结。同时也希望可以通过⽂章,结识更多朋友,多交流,互相学习,共同进步。另⽂章若有不对之处,还望指出与不吝赐教。
1 微信⼩程序基本知识与概念
微信⼩程序开发,⼊门算是⾮常简单,只要看官⽂⽂档即可⼩程序简易教程。如何申请⼩程序账号,如何开发⾃⼰第⼀个⼩程序,如何发布,这⼀
系列hello world操作官⽅⽂档都有⼿把⼿教学。⼩程序开发的每个步骤,提供的能⼒⽂档⾥都有,个⼈觉得,做⼩程序开发,有事没事都看下⽂
档,因为⼩程序更新⽐较快速,同时⼀些细⼩的能⼒我们可能会漏掉,所以多看⽂档。
image
接下来简单介绍下各个⽂件:
全局配置⽂件app.json
对于⼀个⼩程序项⽬⽽⾔,最重要的⽂件是,它也是开发⼯具识别⼀个⽂件夹是否为⼩程序项⽬的标识。当使⽤开发者⼯具创建⼀个项
⽬是,如果选择的是空⽂件夹,它会创建⼀个新的项⽬。如果是⼀个有⽂件的⽂件夹,它会看该⽂件夹中是否有⽂件,如果有,则它会认
为是⼀个⼩程序项⽬,则会打开该项⽬,如果⽂件夹中没有⽂件,则提⽰⽆法创建项⽬。
image
必须放置于项⽬的根⽬录下,它是⼩程序项⽬的全局配置⽂件。在⼩程序代码包准备完成进⾏启动后(下⽂会详细介绍⼩程序从⽤户点
击打开⼩程序到⼩程序销毁的整个过程),会先读取⽂件,进⾏⼩程序的初试化,⽐如初始化整个⼩程序外框样式,获取⾸页页⾯地址
"pages": [
"pages/index/index",
"pages/log/log"
]
在中,pages选项是必须配置的。该配置项注册了⼩程序所有页⾯的地址,其中每⼀项都是页⾯的 路径+⽂件名 。配置的字符串其实就
是每个页⾯wxml路径,去掉.wxml后缀。因为框架会⾃动去寻找路径下.json、.js、.wxml、.wxss四个⽂件进⾏整合。也就意味着.json、.js、
.wxss这三个⽂件的⽂件名必须要和.wxml的⼀致,否则不⽣效。所以⼀个页⾯⾄少必须得有.wxml⽂件。
总结:
页⾯的.json、.js、.wxss⽂件必须与.wxml⽂件同名,否则不⽣效
每个页⾯都必须pages下注册,没有注册的页⾯,如果不访问,编译能通过,⼀旦试图访问该页⾯则会报错
可以通过在pages下添加⼀个选项快速新建⼀个页⾯,开发⼯具会⾃动⽣成对应的⽂件
window
"window":{
"enablePullDownRefresh": ture,
functionalPages
这个是结合插件使⽤的,因为微信⼩程序插件有很⼤限制,插件⾥提供的api很有限, 和 tPayment 在插件中不能使⽤,如
果需要获取⽤户信息和进⾏⽀付,就必须通过插件提供的功能也实现。当你的⼩程序下的插件启⽤了插件功能也时,必须设置该选项为true
⼩程序插件必须挂载在⼀个微信⼩程序中,⼀个⼩程序也只能开通⼀个插件。当你⼩程序开通的插件启⽤了插件功能也
时,必须设置该选项为true
image
⼩程序启动会有两种情况,⼀种是「冷启动」,⼀种是「热启动」。 假如⽤户已经打开过某⼩程序,然后在⼀定时间内
再次打开该⼩程序,此时⽆需重新启动,只需将后台态的⼩程序切换到前台,这个过程就是热启动;冷启动指的是⽤户⾸
次打开或⼩程序被微信主动销毁后再次打开的情况,此时⼩程序需要重新加载启动。
上⾯的流程图包含了所有内容,但毕竟⽂字有限,接下来详细说下⼏个点。
1. ⼩程序会先检测本地是否有代码包,然后先使⽤本地代码包进⾏⼩程序启动,再异步去检测远端版本。这就是⼩程序的离线能⼒,相对于H5,
这是优点,能加快⼩程序启动速度。
if (e('getUpdateManager')) {
//检测是否有版本更新
var updateManager = ateManager()
kForUpdate(function (res) {
// 请求完新版本信息的回调,有更新
if (ate) {
ading({
title: '检测到新版本',
})
}
})
teReady(function () {
ading();
dal({
title: '更新提⽰',
content: '新版本已经准备好,是否重启应⽤?',
success: function (res) {
if (m) {
//清楚本地缓存
image
可以模拟任意场景值、设置页⾯参数、模拟更新等。基本满⾜了所有的调试。不过还有⼀些效果,开发⼯具和真机可能会不同,所以还是需要在真
机上确认。
image
2 重点介绍⼏个组件
接下来说说使⽤频率⽐较多,功能强⼤,但⼜有⽐较多坑的⼏个组件
2.1 web-view
web-view的出现,让⼩程序和H5⽹页之前的跳转成为了可能。通过把H5页⾯放置到web-view中,可以让H5页⾯在⼩程序内运⾏。同时在H5页
⾯中也可以跳转回⼩程序页⾯。可以说是带来了很⼤的便利,但同时由于web-view的诸多限制,⽤起来也不是很舒服。
1. 需要打开的H5页⾯必须在后台业务页⾯中配置,这其中还有个服务校验。另外H5页⾯必须是https协议,否则⽆法打
开
2. web-view中⽆法在页⾯中调起分享,如果需要分享,⽐如跳回⼩程序原⽣页⾯
3. ⼩程序与web-view⾥H5通信问题。⼩程序向web-view传递,不敏感信息可以通过页⾯url传递。如果是敏感信息⽐如
⽤户token等,可以让服务端重定向,⽐如请求服务端⼀个地址,让他把敏感信息写在cookie中,再重定向到我们的
image
因为web-view是默认铺满全屏的,也就是web-view宽⾼和屏幕宽⾼⼀样。然后H5页⾯这是⾼度100%,这是相对web-view的⾼度,也是屏幕⾼
度。但是关键问题:web-view⾥H5页⾯是从导航栏下开始渲染的。这就导致了H5页⾯溢出了屏幕,⽆法达到全屏效果。
解决⽅法
这个问题我在前段时间的实际项⽬碰到过,我们要做个H5游戏,要求是全屏,刚开始我也是设置⾼度100%。后来发现底部⼀块不见了。我的解
决⽅法⽐较粗暴,如果有更好的解决⽅法,欢迎评论交流。
我的解决⽅法是:通过拼接宽⾼参数在H5页⾯url上,这个宽⾼是在web-view外层计算好的。H5页⾯直接读取url上的宽⾼,动态设置页⾯的宽
⾼。页⾯⾼度的计算,根据上图,很显然就是屏幕⾼度减去导航栏⾼度。宽度都是⼀样的,直接是屏幕宽度。
但问题⼜来了,貌似没有途径获取导航栏⾼度。⽽且对于不同机型的⼿机,导航栏⾼度不同。经过了对多个机型导航栏跟屏幕⾼度的⽐较。发现了
⼀个规律,导航栏⾼度与屏幕⾼度、屏幕宽⾼⽐有⼀定的关系。所以根据多个机型就计算出了这个⽐例。这解决了95%以上⼿机的适配问题,只
有少数机型适配不是很好。到基本实现了全屏效果。具体代码如下:
onLoad (options) {
//同步获取屏幕信息,现在⽤到的是屏幕宽⾼
var res = temInfoSync();
if (res) {
var widHeight = Height;
//对于⼤多数⼿机,屏幕⾼度/屏幕宽度 = 1.78。此时导航栏占屏幕⾼度⽐为0.875
var raito = 0.875;
if (Height / Width > 1.95) {
//对于全屏⼿机,这个占⽐会更⾼些
raito = 0.885;
} else if (Height / Width > 1.885) {
raito = 0.88;
}
//做兼容处理,只有微信版本库⾼于6.7.2,有导航栏才去兼容,否则可以直接使⽤⾼度100%。BarHeight是⼿机顶部状态栏⾼度
//如果微信版本号⼤于6.7.2,有导航栏
if (eVersion(n, "6.7.2") > 0) {
widHeight = (widHeight * raito) + (BarHeight || 0);
}
e({
//将H5页⾯宽⾼拼接在url上,赋值给web-view的src即可加载出H5页⾯
webview_src: rams(h5_src, {
"height": widHeight,
"width": Width
})
})
}
}
wxml⽂件
scroll-with-animation = "true" style="height: 100%; white-space:nowrap"> 2.3 canvas 画布标签,它是原⽣组件,所以它必须位于屏幕最上边,⽽且是不能隐藏的。所以如果想要使⽤canvas动态⽣成分享照⽚。那你要设置她的宽⾼ 和屏幕⼀样。要不导出为照⽚时就会失真。因为这个原因,所以⽣成分享照⽚还是有服务端实现吧,照⽚失真太严重了。 3 formid收集 给⽤户发送消息对⼀个⼩程序是⾮常重要的,它可以召唤回⽤户,导量效果⾮常明显。我们可以通过模板消息想⼩程序⽤户发送消息,但前提是我 们得获取到openid和formid。⽤户登录我们即可即可获取到⽤户openid。⽽只要⽤户有点击⾏为,我们即可获取到formid获取formid。所以说 formid是很重要的。我们可以提前收集好formid,在需要的时候给⽤户推送消息。我们可以个每个button都包上form标签,只要有⽤户点击⾏ 为都可以收集到formid. 点击 我们实现⼀个formid收集系统,为了尽量减少冗余代码和减少对业务的影响,我们的设计是这样的 1. 在整个页⾯的最外层包裹form标签,不是每个button都包裹⼀个,这样只要是页⾯中的button有点击都能获取到formid。 formTpye=submit 2. formid保存在全局变量数组中,当⼩程序切换到后台是⼀次性发送。 3. 对于需要实时发送消息的,不添加值全局数组中,直接保存在页⾯变量中。 wxml⽂件 点击 点击 ⽂件 //每次⽤户有点击,都将formid添加到全局数组中 formSubmit(e) { //需要实时发送的,不添加 if(g){ formid = ; return; } (); } image 前⾯状态⼩程序代码⼤⼩是650Kb左右,这是下载耗时(虽然跟⽤户⽹络有关,但这个是全部⽤户平均时间)是1.3s左右。但是经过优化,将代 码包降低⾄200kb左右时。下载耗时只有0.6s左右。所以说,代码包减少500kb,下载耗时能减少0.5s。这个数据还是⾮常明显和。所以说,在 不影响业务逻辑的情况下,我们⼩程序代码包应该尽可能地⼩。那么如何降低代码包⼤⼩呢?以下有⼏点可以参考 1. 因为我们上传代码到微信服务器时,它会将我们的代码进⾏压缩的,所以⽤户下载的代码包并不是我们开发时的那个⼤⼩。对此,开发时也没 必要删空⾏、删注释这些。在开发⼯具项⽬详情中可以看到上次上传⼤⼩,这个⼤⼩就是⽤户最终使⽤的⼤⼩。如果觉得微信压缩还不够好, 可以通过第三⽅⼯具对我们代码进⾏⼀次压缩再上传,然后对⽐效果,有没有更⼩。这个没有使⽤过。如果有什么好⼯具,欢迎推荐。 image 只不过错误信息是包括堆栈等⽐较详细的错误信息,然后当上传时我们并不需要这么信息,第⼀浪费宽带,第⼆看着累⼜⽆⽤。我们需要的信息 是:错误类型、错误信息描述、错误位置。 thirdScriptError aa is not defined;at pages/index/index page test function ReferenceError: aa is not defined at (127.0.0.1:62641/appservice/pages/index/:17:3) at e. enumerable: true, writable: true, value: function(){ let options = arguments[0] || {}; //对于发送错误信息的接⼝不收集,防⽌死循环 var regexp = new RegExp("xxxx/error","g"); if (()) { //这⾥要执⾏原来的⽅法 return (this, options) } //这⾥拦截请求成功或失败接⼝,拿到请求后的数据 ["success", "fail"].forEach((methodName) => { let defineMethod = options[methodName]; options[methodName] = function(){ try{ //在重新定义函数中执⾏原先的函数,不影响正常逻辑 defineMethod && (this, arguments); //开始信息收集 let statusCode, result, msg; //请求失败 if (methodName == 'fail') { statusCode = 0; result = 'fail'; msg = ( arguments[0] && arguments[0].errMsg ) || "" } //请求成功, //收集规则为: }; }) return (this, options) } 4 总结 洋洋洒洒写了这么多,或许有些地⽅说的不太清楚,慢慢锻炼吧。然后后⾯⼏点只是挑了重要的讲,我相信有过⼩程序开发经验的朋友应该没问
发布评论