微信小程序
TODO: 持续更新中。。。
原理和思想
小程序是基于 WEB 规范,采用 HTML,CSS 和 JS 等搭建的一套框架.
实现原理:底层是基于 Webview 来实现的,并没有发明创造新技术,整个框架体系,比较清晰和简单,基于 Web 规范,保证现有技能价值的最大化,只需了解框架规范即可使用已有 Web 技术进行开发。易于理解和开发。
数据传递(setData):小程序的视图层目前使用 WebView 作为渲染载体,而逻辑层是由独立的 JavascriptCore 作为运行环境。在架构上,WebView 和 JavascriptCore 都是独立的模块,并不具备数据直接共享的通道。当前,视图层和逻辑层的数据传输,实际上通过两边提供的 evaluateJavascript 所实现。即用户传输的数据,需要将其转换为字符串形式传递,同时把转换后的数据内容拼接成一份 JS 脚本,再通过执行 JS 脚本的形式传递到两边独立环境。而 evaluateJavascript 的执行会受很多方面的影响,数据到达视图层并不是实时的。
组件机制:引入组件化机制,但是不完全基于组件开发,跟 vue 一样大部分 UI 还是模板化渲染,引入组件机制能更好的规范开发模式,也更方便升级和维护。
生命周期(函数)
| 小程序的生命周期 | 说明 |
|---|---|
| onLaunch | 小程序初始化 当小程序初始化完成时,会触发 onLaunch(全局只触发一次) |
| onShow | 小程序显示 当小程序启动,或从后台进入前台显示,会触发 onShow |
| onHide | 小程序隐藏 当小程序从前台进入后台,会触发 onHide |
| onError | 错误监听函数 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息 |
| onPageNotFound | 页面不存在监听函数 当小程序出现要打开的页面不存在的情况,会带上页面信息回调该函数,详见下文 |
| 页面的生命周期 | 说明 |
|---|---|
| onLoad | 页面加载:一个页面只会调用一次,可以在 onLoad 中获取打开当前页面所调用的 query 参数 |
| onReady | 页面初次渲染完成:一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互;对界面的设置如 wx.setNavigationBarTitle 请在 onReady 之后设置 |
| onShow | 页面显示:每次打开页面都会调用一次 |
| onHide | 页面隐藏 |
| onUnload | 页面卸载:当 redirectTo 或 navigateBack 的时候调用 |
| onPullDownRefresh | 下拉刷新:需要在 app.json 的 window 选项中或页面配置中开启 enablePullDownRefresh;当处理完数据刷新后,wx.stopPullDownRefresh 可以停止当前页面的下拉刷新。 |
| onReachBottom | 上拉触底:可以在 app.json 的 window 选项中或页面配置中设置触发距离 onReachBottomDistance;在触发距离内滑动期间,本事件只会被触发一次 |
| onShareAppMessage | 用户转发:只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮;用户点击转发按钮的时候会调用;此事件需要 return 一个 Object,用于自定义转发内容 |
| onPageScroll | 滑动页面 |
| onTabItemTap | 当前是 tab 页时,点击 tab 时触发 |
| 组件的生命周期 | 说明(同 vue1.0) |
|---|---|
| created | 组件生命周期函数,在组件实例进入页面节点树时执行,注意此时不能调用 setData |
| attached | 组件生命周期函数,在组件实例进入页面节点树时执行 |
| ready | 组件生命周期函数,在组件布局完成后执行,此时可以获取节点信息(使用 SelectorQuery ) |
| moved | 组件生命周期函数,在组件实例被移动到节点树另一个位置时执行 |
| detached | 组件生命周期函数,在组件实例被从页面节点树移除时执行 |
组件系统及 template
组件化是实现工程化的根本,现前端优秀框架无一不实现了组件化开发。但从文件形式到数据传递机制来看,组件的又多了一套完全照搬老 vue 的生命周期函数,且其 behaviors 貌似是 polymer 框架早已废弃的做法,对于 template 更是白受诟病,总之小程序做的并不完美。但相比于简单的写静态页面,component 和 template 及 slot 结合起来用还是很方便的, 勉强可以达到 vue/react 的组件效果,期待并相信腾讯团队的更新及维护。
- 使用心得:
- template 支持解构赋值用起来很爽;
- component 的事件传递数据机制的穿透,实现跨组件传递数据的效果挺好的,虽然思路与做法看起来极像 polymer。
数据传递
方式:
- 简单粗暴不响应式:
- 全局变量:主要针对整个 app 共享的变动频繁的数据
- 本地存储:主要针对整个 app 共享的变动相对稳定的数据,对于嵌套复杂的数据结构本地存储的数据在响应式更新方面可能会不和预期
- props 传递:顺应主流思路及前端友好
- 路由传参:灵活方便
- 事件对象(主要针对 component)
踩坑指南
- 1 移动端适配:
- 字体/边框单位:对于字体也要用 rpx(以 iphone6 750px 屏为参考,1rpx=.5pt),边框也可以用 rpx
- 其它单位(rpx/px/pt):以 iphone6 750px 屏为参考(1rpx=1pt)
- 文件路径: 除了 js 其它小程序文件都支持从根目录引入,对于图片路径可能还有其它限制;
- 音乐播放器:
- 多个音频的自定义组件,使用背景音乐管理器暂停及播放方面会存在模拟机上真机上运行正常的情况;
- 多个音频组件生命周期回调上也有不合预期的 bug;
- 音频播放器及背景音乐播放器 andriod 上适配性不太好;
- 五月 8 日起,微信小程序不支持 iOS 「虚拟支付」
- 关于分享
- 进入小程序的方式(5 种常见场景值):
- 线下扫码(扫码 1011-1013): 小程序最简单的获取方式就是是二维码。大家可以打开扫一扫,通过微信扫描线下二维码的方式进入小程序。
- 微信搜索(1005,1054): 在微信客户端最上方的搜索窗口,你可以通过搜索获取一个小程序。
- 公众号关联(1020,1043): 同一主体的小程序和公众号可以进行关联,并相互跳转,该功能需要经开发者自主设置后使用。一个公众号可以绑五个小程序,但一个小程序只能被一个公众号绑定。你可以通过公众号查看并进入所绑定的小程序,当然,你也可以通过小程序查看并进入所关联的公众号。
- 好友推荐(转发 1008):当你发现一个好玩的或者实用的小程序,可以将这个小程序,或者它的某一个页面转发给好友或群聊。不过小程序无法在朋友圈中发布分享。
- 历史记录(1027): 当你使用过某个小程序后,在微信客户端的“发现-小程序”里的列表,就可以看到这个小程序,想要再次使用它时,通过列表中的历史记录就可以进入。在“发现-小程序”中,也可以通过搜索进入小程序。
- 进入小程序的方式(5 种常见场景值):
- 关于分享
分享的情形(进入小程序方式的子集):
- 小程序内部分享:约定好 分享参数(userId,topicId,scene 等),这些分享参数可用于埋点统计,进入小程序访问数据等
- H5 公众号分享(二维码):各种扫码方式
- H5 公众号朋友圈:扫码或者连接
- H5 公众号 消息转发
分享的方式:
- 小程序自带原生分享(右上角)
- 用户自定义分享按钮分享(不推荐,各种坑)
- 分享的 开与关全是通过微信小程序函数(onShareAppMessage(options),wx.hideShareMenu(OBJECT))实现
分享的结果(政策有变,只能分享无法回调成败,只有分享回调 TODO:)
- 授权的情形:
- js 回调授权弹窗(已废弃)
- 授权按钮点击后跳出授权弹窗(推荐):只有这一步之后授权设置弹窗弹出后才有设置选项
- 授权的情形:
项目经验及教训
- 分工合作:
- 对前端本身:
- 涉及合作就要坚持 code review,具体就是开分支,提 pr,cr 最终 merge;
- 分离 UI 逻辑与业务逻辑,保证各个模块之间高内聚低耦合,职责分明,不重复不遗漏;
- 制定 good practise 保证代码维护性,扩展性,复用性,测试性等的可靠保证(这点对个人对团队均意义重大);
- 一个 feature 或 bug,给自己规定一个 deadline,如果搞不定,务必及时转变思路或求助他人;
- 对后端:
- 首先与他们探讨业务场景,约定数据骨架结构(Schama),约定规范统一详细的错误码;
- 约定接口出参入参,约定接口种类,数量
- 测试并使用他们接口,遇到问题或报错,首先看前端本身,然后看他们;务必做到及时反馈
- 对产品:
- 及时熟悉了解他们 prd 文档,领会其设计思路及初衷;
- 根据自己理解,对不明白不理解或有分歧的地方,及时和他们探讨;
- 了解领会 prd 之后,在对前端统筹规划,着手业务逻辑及 UI 逻辑的划分;
- 对 UI:及时交互反馈
- 对前端本身:
- 职责分化:
- 根据业务特点及行业经验,及 CTO 的合理化建议,首先务必明确哪些事情前端做,哪些后端做;
- 不要因为任何原因拒绝做(时间紧迫)或主动做(时间充裕),只关注前端领域的事情,明确前后端职责并始终坚持前前后端分离;
- 为更好协作可以了解后端做事逻辑及特点,不代表做不属于前端的事情;
参考文档
- 官方文档—(比较粗糙混乱 🔍 功能弱爆且常见 bug 甚至没有提示)
- 小程序实现原理解析
- Web Components

Leave a Comment