前言
开始微信小程序的开发之前,肯定是先去看官方文档,当你将文档通篇看完过后,了解了微信小程序的开发流程以及它和H5开发有什么区别?你是不是有点蒙了,没关系,跟着我回顾一点重点吧。
什么是微信小程序?
小程序是一种不需要下载安装,扫一扫即可使用的应用,提倡“用完即走”的理念。对于开发者而言,小程序开发门槛相对较低,难度不及APP,能够满足简单的基础应用,适合生活服务类线下商铺以及非刚需低频应用的转换。小程序能够实现消息通知、线下扫码、公众号关联等七大功能。其中,通过公众号关联,用户可以实现公众号与小程序之间相互跳转。也可以通过APP分享,实现小程序跳转到APP的功能。
小程序和原生App相比较有什么优势?
小程序适合拿些应用场景
场景 | 应用 |
---|---|
餐厅点餐 | 基于LBS搜索附近的餐厅,进店用进行扫码点餐、支付 |
零售 | 基于LBS搜索附近的商店,买点水果或零食,下单后送货上门 |
公交 | 公交车站扫一扫就知道公交什么时候来 |
娱乐 | KTV点歌,总是快人一步 |
票务客运 | 电影票、演出票、汽车票 |
加油站缴费 | 告别排队缴费,扫一扫不用下车就能搞定 |
酒店旅行 | 旅行酒店预订、周边攻略、目的地、游记等 |
快递 | 查订单、查物流、查配送 |
政务 | 排号、业务办理。查公积金、车辆违章 |
医疗 | 提前挂号、就医后扫码支付,直接拿药 |
景区 | 门票购买、自助检票、场景导航 |
展会 | 登记注册、展会流程 |
硬件 | 扫码打印照片、智能设备控制 |
游戏抽奖 | 开年会或搞活动,“扫一扫抽奖”,不解释 |
小程序采用了什么技术方案?
我想从技术的角度来谈谈我对微信小程序的理解,我觉得小程序本身是一个非常优秀的Hybrid App的技术方案。有很多值得学的地方,可以应用到我们Hybrid App的技术方案设计中来。了解和学习小程序技术原理也能更好的优化我们的代码。
渲染层和逻辑层分离
小程序采用了双线程模型,将渲染层和逻辑层分开。逻辑层通过JsCore来解析和执行,渲染层是通过 webview 来渲染。而常见的 Hybrid 离线包的方案大多使用 webview 同时实现页面的渲染和js的解析。
小程序模型相较于Hybird模型的好处:
- js无法动态的在页面插入节点和干预页面的渲染,解决了安全和管控的问题,否则小程序的上线审核就变得毫无意义。
- 渲染层和逻辑层的分离,减轻了webview的压力,js的执行和页面的渲染可以并行,不会出现js执行卡主页面渲染的情况。
- 多个页面可以共享一个JS运行环境,数据很方便的共享,整个小程序的生命周期共享同一个上下文,接近App的体验。
坏处在于:
- 由于隔离js的runtime,无法使用JS操作webview中的DOM对象和BOM对象。与任何和页面渲染有关的操作,只能通过setData把数据从JsCore传递到webview。
- 多了很多webview和JSCore数据传输的消耗,数据需要序列化成字符串格式进行传输。
离线包加载
离线包加载,常见的Hybrid App通过webview加载H5页面,前端页面都是放在服务器端。虽说保证了灵活性,但是加载性能收网速影响大,页面切换白屏时间长。小程序离线包的加载方式,一次性加载所有的前端资源到本地再解压,大大提升了用户体验。不过微信官方为了防止下载离线包的时间过程,也严格限制了小程序包的体积。(分包加载情况下子包大小不能超过2M,也就是初次打开加载的资源不能超过2M)
多webview架构
多webview的页面架构,小程序每新开一个页面,都会用一个新的webview来渲染。为了防止webview对内存的消耗,小程序限制页面层级不能超过10层。
预加载webview
预加载webview,微信会预加载多一个webview(ios平台)放后台,用户打开小程序时省去初始化webview时间。
微信小程序主流框架对比
WePY
WePY (发音: /'wepi/)是一款让小程序支持组件化开发的框架,通过预编译的手段让开发者可以选择自己喜欢的开发风格去开发小程序。框架的细节优化,Promise,Async Functions的引入都是为了能让开发小程序项目变得更加简单,高效。
WePY提供了类vue.js的语法风格和特性,它算是最早发布的小程序开发框架,所以也是应用最广泛的框架了。
坑点: wepy组件的实现方式使用的是静态编译组件,即组件是在编译阶段编译进页面的。每个组件都是唯一的一个实例,如果多个组件共享同一个数据。并且静态编译组件。导致组件A,在页面A和页面B被引用,会copy两份代码到页面A和页面B内部,这样拆分组件并没有对包的体积有任何减少。
mpvue
由美团点评团队开发,它和wepy一样提供了类Vue.js的开发体验。这个框架的原理相比wepy要更加复杂一点。框架基于 Vue.js 核心,mpvue 修改了 Vue.js 的 runtime 和 compiler 实现,使其可以运行在小程序环境中,从而为小程序开发引入了整套 Vue.js 开发体验。
Taro
Taro是由京东凹凸实验室团队开源的一套遵循 React 语法规范的多端统一开发框架。支持用 React 的开发方式编写一次代码,生成能运行在微信小程序、H5、React Native 等的应用。
框架对比
直接看下面这个对比表格吧,框架推出的时间按从左到右排序。具体使用哪个框架需要根据团队技术栈、技术需求以及框架特点、特性进行选型和权衡。
微信小程序 | WePY | mpvue | Taro | |
---|---|---|---|---|
开发者 | 微信官方 | 腾讯团队 | 美团点评团队 | 京东凹凸实验室团队 |
语法规范 | 小程序规范 | 类Vue.js规范 | Vue.js规范 | React规范 |
模板系统 | 字符串模板 | 字符串模板 | 字符串模板 | JSX |
类型系统 | 不支持 | 业务代码 | 业务代码 | 业务代码 + JSX 模板 |
组件规范 | 小程序组件 | 小程序组件 | HTML 标签 + 小程序组件 | 小程序组件 |
样式规范 | wxss | sass/less/stylus | sass/less/postcss | sass/less/postcss |
组件化 | 小程序组件化 | 自定义组件化 | vue组件化规范 | React 组件化规范 |
多端复用 | 无 | 复用为 H5 | 复用为 H5* | 复用为 H5* |
自动构建 | 无 | 内建构建系统 | Webpack 构建 | 内建构建系统 + Webpack |
上手成本 | 全新学习 | 熟悉 Vue.js + WePY | 熟悉 Vue.js | 熟悉 React |
数据流管理 | 不支持 | Redux | Vuex | Redux |
关注量 | * | 13.7k | 13k | 7.6k |
mpvue 将通过 weex 支持移动端,Taro 将通过 React Native 支持移动端
框架选型建议:
除了原生小程序开发,其他3个框架都支持H5复用,具体根据你现在已有项目的技术栈来选择。如果你的项目使用Vue.js开发,那肯定就在WePY和mpvue之间选择,当然我更推荐mpvue,它更接近于Vue.js全家桶的开发模式。如果现有项目是React开发的当然是选Taro了,其他框架还是要去学习,迁移也比较麻烦。
那原生开发方式是不是就不推荐呢?当然不是。如果你是对Vue.js和React都不熟的菜鸟,或者说你现在没有项目需要迁移,完全是重新开发,那么我更推荐原生的方式。使用原生小程序开发,现在可能会麻烦一点,但是遇到什么问题,官方文档都说的很清楚,不需要再去管Vue.js或React本身有什么坑。学习一下小程序开发都有些什么,没什么不好的。
微信小程序常用UI库对比
开发微信小程序的过程中,选择一款好用的组件库,可以达到事半功倍的效果。自从微信小程序面世以来,不断有一些开源组件库出来,下面5款就是排名比较靠前,用户使用量与关注度比较高的小程序UI组件库。
WeUI WXSS
WeUI WXSS是腾讯官方UI组件库WeUI的小程序版,提供了跟微信界面风格一致的用户体验。
GitHub地址:https://github.com/Tencent/weui-wxss
npm下载:npm i weui-wxss
iView WeApp
iView是TalkingData发布的一款高质量的基于Vue.js组件库,而iView weapp则是它们的小程序版本。
GitHub地址:https://github.com/TalkingData/iview-weapp
npm下载:npm i iview-weapp
ZanUI WeApp
ZanUI WeApp是有赞移动 Web UI 规范 ZanUI 的小程序现实版本,结合了微信的视觉规范,为用户提供更加统一的使用感受。
GitHub地址:https://github.com/youzan/zanui-weapp
npm下载:npm i zanui-weapp
另外,ZanUI也使用 mpvue 重写 zanui-weapp,实现了其中所有组件。
GitHub地址:https://github.com/samwang1027/mpvue-zanui
npm下载:npm i mpvue-zanui
MinUI
MinUI 是蘑菇街前端开发团队开发的基于微信小程序自定义组件特性开发而成的一套简洁、易用、高效的组件库,适用场景广,覆盖小程序原生框架,各种小程序组件主流框架等,并且提供了专门的命令行工具。
GitHub地址:https://github.com/meili/minui
Wux WeApp
Wux WeApp也是一个非常不错的微信小程序自定义 UI 组件库,组件比较丰富,值得使用。
GitHub地址:https://github.com/wux-weapp/wux-weapp
npm下载:npm i wux-weapp
开始开发
注册小程序账号
准备一个没有注册过公众号的邮箱,然后访问微信小程序介绍页面,并点击底部的「前往注册」按钮,再按照提示填写个人信息,最后进入邮箱激活账号即可。详细流程请参考官方文档。
安装开发者工具
为了帮助开发者简单和高效地开发和调试微信小程序,我们在原有的公众号网页调试工具的基础上,推出了全新的 微信开发者工具,集成了公众号网页调试和小程序调试两种开发模式。
使用公众号网页调试,开发者可以调试微信网页授权和微信JS-SDK 详情
使用小程序调试,开发者可以完成小程序的 API 和页面的开发调试、代码查看和编辑、小程序预览和发布等功能。小程序开发者工具是使用 NW.js 编写的。
开发者工具下载地址:
正式版:下载地址
Beta版:同「正式版」不同,一些新的特性和 bug 修复以 beta 方式先发布。下载地址
使用开发者工具
开发者工具主界面,从上到下,从左到右,分别为:菜单栏、工具栏、模拟器、编辑器、调试器 五大部分。
菜单栏:开发者工具菜单选型
工具栏:集成了窗口管理,常用的编译、发布、调试操作等。
模拟器:提供小程序的运行环境,模拟小程序在微信客户端的表现。小程序的代码通过编译后可以在模拟器上直接运行。
编辑器:简单 IDE 功能,可以打开多个文件进行编辑,实现自动保存、实时预览、自动补全等功能。
调试器:订制版的Chrome DevTools
,与在 Chrome 上进行调试操作基本一致。
工具栏介绍
左侧:主要是模拟器、编辑器、调试器和小程序云开发控制台的视图开关,可以控制对应视图的开启关闭。
中间:开发、编译、测试和上线相关按钮,我们在开发和测试小程序中会经常使用,最常用的有:
- 编译模式:可以自定义编译条件,包括启动页面、启动参数、进入场景等
- 预览、真机调试:可以在手机上直接预览效果,或直接进行真机远程 Debug 功能
- 清缓存:可以清除数据缓存、文件缓存、授权数据、登录状态等操作
- 上传:小程序开发测试通过后,点击上传之后可以在小程序管理后台申请测试版和提交审核,审核通过后就可以发布上线了
- 测试:免费的云真机测试环境以及一整套测试方案,用于检测小程序程序缺陷、评估小程序产品质量。
小程序的配置
小程序有三个重要的配置文件,分别是工具项目配置、全局配置、页面配置
project.config.json
:开发者工具的编译设置(是否使用 ES6 语法等)、界面设置,以及云函数相关的 cloudfunctionRoot等。app.json
:对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。page.json
:相对于 app.json 更细粒度的单页面窗口表现进行配置,页面中配置项会覆盖 app.json 的 window 中相同的配置项。
视图层 View
框架的视图层由 WXML 与 WXSS 编写,由组件来进行展示。将逻辑层的数据反应成视图,同时将视图层的事件发送给逻辑层。
- WXML(WeiXin Markup language) 用于描述页面的结构。
- WXS(WeiXin Script) 是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。
- WXSS(WeiXin Style Sheet) 用于描述页面的样式。
- 组件(Component)是视图的基本组成单元。
注意:
- wxs 不依赖于运行时的基础库版本,可以在所有版本的小程序中运行。
- wxs 与 javascript 是不同的语言,有自己的语法,并不和 javascript 一致。
- wxs 的运行环境和其他 javascript 代码是隔离的,wxs 中不能调用其他 javascript 文件中定义的函数,也不能调用小程序提供的API。
- wxs 函数不能作为组件的事件回调。
- 由于运行环境的差异,在 iOS 设备上小程序内的 wxs 会比 javascript 代码快 2 ~ 20 倍。在 android 设备上二者运行效率无差异。
逻辑层 App Service
小程序开发框架的逻辑层使用 JavaScript 引擎为小程序提供开发者 JavaScript 代码的运行环境以及微信小程序的特有功能。
逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
开发者写的所有代码最终将会打包成一份 JavaScript 文件,并在小程序启动的时候运行,直到小程序销毁。这一行为类似 ServiceWorker,所以逻辑层也称之为 App Service。
在 JavaScript 的基础上,我们增加了一些功能,以方便小程序的开发:
- 增加 App 和 Page 方法,进行程序和页面的注册。
- 增加 getApp 和 getCurrentPages 方法,分别用来获取 App 实例和当前页面栈。
- 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
- 每个页面有独立的作用域,并提供模块化能力。
注意:小程序框架的逻辑层并非运行在浏览器中,因此 JavaScript 在 web 中一些能力都无法使用,如 window,document 等。
组件
小程序一共提供 8 大类 30 多个组件,包括视图容器、基本内容、表单组件、导航、媒体组件、画布、地图、开放能力。
原生组件
小程序中的部分组件是由客户端创建的原生组件,这些组件有:
camera、canvas、input、live-player、live-pusher、map、textarea、video
原生组件的使用限制
由于原生组件脱离在 WebView 渲染流程外,因此在使用时有以下限制:
- 原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。
后插入的原生组件可以覆盖之前的原生组件。 - 原生组件还无法在 scroll-view、swiper、picker-view、movable-view 中使用。
- 部分CSS样式无法应用于原生组件,例如:
- 无法对原生组件设置 CSS 动画
- 无法定义原生组件为 position: fixed
- 不能在父级节点使用 overflow: hidden 来裁剪原生组件的显示区域
- 原生组件的事件监听不能使用 bind:eventname 的写法,只支持 bindeventname。原生组件也不支持 catch 和 capture 的事件绑定方式
- 在iOS下,原生组件暂时不支持触摸相关事件。
在工具上,原生组件是用web组件模拟的,因此很多情况并不能很好的还原真机的表现,建议开发者在使用到原生组件时尽量在真机上进行调试。
cover-view 与 cover-image
为了解决原生组件层级最高的限制。小程序专门提供了 cover-view 和 cover-image 组件,可以覆盖在部分原生组件上面。这两个组件也是原生组件,但是使用限制与其他原生组件有所不同。
自定义组件
开发者可以将页面内的功能模块抽象成自定义组件,以便在不同的页面中重复使用;也可以将复杂的页面拆分成多个低耦合的模块,有助于代码维护。自定义组件在使用时与基础组件非常相似。
插件
插件是对一组 js 接口、自定义组件或页面的封装,用于嵌入到小程序中使用。插件不能独立运行,必须嵌入在其他小程序中才能被用户使用;而第三方小程序在使用插件时,也无法看到插件的代码。因此,插件适合用来封装自己的功能或服务,提供给第三方小程序进行展示和使用。
插件开发者可以像开发小程序一样编写一个插件并上传代码,在插件发布之后,其他小程序方可调用。小程序平台会托管插件代码,其他小程序调用时,上传的插件代码会随小程序一起下载运行。
相对于普通 js 文件或自定义组件,插件拥有更强的独立性,拥有独立的 API 接口、域名列表等,但同时会受到一些限制,如一些 API 无法调用或功能受限。对于一些特殊的接口,如wx.login
和wx.requestPayment
,虽然插件不能直接调用,但可以使用插件功能页来间接实现。
小程序开发基础
数据驱动
微信小程序是数据驱动模型,页面加载时,data 将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型:字符串,数字,布尔值,对象,数组。
// wxml
<view>{{ message }}</view>
// wxs
Page({
data: {
message: 'Hello MINA!'
}
})
注意:小程序不支持复杂的表达式,目前支持简单的三元、加减和逻辑判断。
生命周期回调函数
// pages/test.js
Page({
// 页面的初始数据
data: { },
// 生命周期函数--监听页面加载
onLoad: function (options) { },
// 生命周期函数--监听页面初次渲染完成
onReady: function () { },
// 生命周期函数--监听页面显示
onShow: function () { },
// 生命周期函数--监听页面隐藏
onHide: function () { },
// 生命周期函数--监听页面卸载
onUnload: function () { },
// 页面相关事件处理函数--监听用户下拉动作
onPullDownRefresh: function () { },
// 页面上拉触底事件的处理函数
onReachBottom: function () { },
// 用户点击右上角分享
onShareAppMessage: function () { }
})
开发中踩过的坑和解决方案
坑点: {{}}
不能执行函数方法,只支持基本的简单运算和ES6拓展运算符。
解决:
- 通过wxs模块解决{{}}中不能执行函数的问题。
- 在使用数据之前,对数据进行计算。
- 如果使用组件,可以使用官方compute扩展
坑点: css样式(background-image)不能引用本地图片资源
解决: 引用线上资源,如果要引用本地图片资源可以用image
标签
坑点: 使用image标签,图片在模拟器和真机上显示不一致
解决: image标签有个mode
属性,如果遇到图片变形使用aspectFit
即可。
坑点: 小程序不支持分享链接到朋友圈
解决: 前端利用canvas
来生成一张带有小程序码的图片保存到本地相册,由用户自行发朋友圈转发。建议保存到真机的图片比预览图大一些(用750像素),这样更清晰,更利于二维码识别。
坑点: 在某些android机型上1rpx无法显示
解决: 小程序布局搞了个新的自适应像素单位rpx
,对于1rpx显示问题可以使用1px
替换1rpx
进行显示。
坑点: 页面路径的层级,最大不能超过10层
解决: 通常这个是页面路由设计和跳转的问题,稍微注意一下就可以了。具体看导航api中wx.navigateTo()和wx.redirectTo()的区别。
坑点: 小程序包大小限制最大8M
解决: 小程序支持分包加载,整个小程序所有分包大小不超过8M
,单个分包/主包大小不能超过2M
。对于8M以上的需求,可以考虑将部分功能使用H5实现,使用webview进行加载。