小程序框架
本章主要内容是小程序框架,包括逻辑层、视图层和flex模型。逻辑层是由JavaScript编写而成的,视图层由WXML和WXSS配合组件构成,flex布局可以确保页面需要适应不同屏幕尺寸及设备类型时元素在恰当的位置。
* 掌握注册程序和页面相关函数的用法;
* 掌握页面路由的方式和模块化的用法;
* 掌握WXML的数据绑定、列表/条件渲染、模板、事件和引用;
* 掌握WXSS的尺寸单位、使用方式和选择器的用法;
* 了解flex布局的基本概念;
掌握flex布局中的容器属性和项目属性。*
3.1 逻辑层
小程序开发框架的逻辑层又称为App Service,是由JavaScript编写和实现的。开发者 写的所有代码最后将被打包成一份JavaScript,并在小程序启动的时候运行,直到小程序被 销毁。
逻辑层的主要作用是处理数据后发送给视图层渲染以及接收视图层的事件反馈。
为了更方便地进行项目开发,小程序在JavaScript的基础上进行了一些优化,例如:
(1)新增App()和Page()方法,分别用于整个应用程序和单独页面的注册。
(2)新增getApp()和getCurrentPages()方法,分别用于获取整个应用实例和当前页面 实例。
(3)提供丰富的微信原生API,例如可以方便地获取微信用户信息、本地存储、扫一扫、微信支付、微信运动等特殊功能。
(4)每个页面具有独立的作用域,并提供模块化功能。
需要注意的是,由于框架不在浏览器中运行,所以JavaScript与浏览器相关的一些功能无法使用,例如document、window等。
3.1.1 注册程序
App()方法
小程序通过使用App(OBJECT)方法进行应用注册,用其指定小程序的生命周期函数。
OBJECT参数如表3-1所示。
表3-1 App()方法的OBJECT参数
属 性
类 型
描 述
触 发 时 机
备 注
onLaunch()
Function
生命周期函数——监听小程序的初始化
当小程序初始化完成时触发
全局只触发1次
onShow()
Function
生命周期函数——监听小程序的显示
当小程序启动或从后台进入前台显示时触发
onHide()
Function
生命周期函数——监听小程序的隐藏
当小程序从前台进入后台隐藏时触发
onError()
Function
错误监听函数
当小程序发送脚本错误或API调用失败时触发
onPageNotFound()
Function
页面不存在函数
当小程序需要打开的页面不存在时触发
其他自定义参数
Any
开发者可以添加自定义名称的函数或数据到OBJECT参数中
用this可以访问
注意:App()方法只能写在小程序根目录下的app.js文件中,并且只能注册1个。
用户可以使用微信web开发者工具在空白app.js文件中直接输入关键词app,此时会自动出现提示列表,如图3-1所示。
图3-1 app.js的代码提示列表
默认选择提示列表中的第一项,直接按回车键就可以自动生成带有生命周期全套函数的代码结构,如图3-2所示。
事实上,App()中的这些函数均为可选函数,开发者可以根据实际需要删除其中的部分函数,或保留这些函数但空着不填充内容。
第12、19行注释语句均提到了小程序后台和前台的概念,具体说明如下。
* 小程序后台:指的是小程序没有在手机当前画面显示,但是并没有被销毁。当用户 单击左上角的按钮关闭小程序或者按设备的Home键离开微信时会进入后台运行 状态。
* 小程序前台:指的是小程序在手机当前画面被使用。当用户再次打开处于后台运行状态的小程序时会重新进入前台运行状态。
注意:只有当小程序进入后台一定时间或者系统资源占用过高时才会被真正地销毁。
图3-2 app.js自动生成App()代码
由图3-2中的代码可见,onLaunch()、onShow()和onError()方法在触发时均会返回参数,用户可以利用这些参数进行状态的判断与处理。其中,onLaunch()与onShow()方法返回的参数名称完全相同,具体如表3-2所示。
表3-2 onLaunch()和onShow()方法返回的参数
字 段
类 型
说 明
path
String
打开小程序的路径
query
Object
打开小程序的query
scene
Number
打开小程序的场景值
shareTicket
String
小程序被转发时会生成一个shareTicket,打开被转发的小程序页面可以获取该参数
referrerInfo
Object
当场景为从另一个小程序/公众号/App打开时返回此字段
referrerInfo.appId
String
跳转前的小程序/公众号/App的appId
referrerInfo.extraData
Object
跳转前的小程序传来的数据,当scene=1037或1038时才支持
支持返回referrerInfo.appId的场景值如表3-3所示。
表3-3 支持返回referrerInfo.appId的场景值
场 景 值
场 景
appId信息的含义
1020
公众号profile页的相关小程序列表
返回来源公众号appId
1035
公众号自定义菜单
返回来源公众号appId
1036
App 分享消息卡片
返回来源应用appId
1037
小程序打开小程序
返回来源小程序appId
1038
从另一个小程序返回
返回来源小程序appId
1043
公众号模板消息
返回来源公众号appId
说明:关于场景值的更多介绍,见附录。
除了函数外,App()也支持添加自定义的全局变量,示例代码如下:
1. App({
2. globalData: {
3. userInfo: null //这是一个全局变量
4. }
5. })
这里,全局变量的名称、取值和数量都可以由开发者自定义。
onPageNotFound()方法
当需要打开的页面不存在时,微信客户端会有一个原生模板页面提示。如果开发者不希望跳转到此页面,想自行处理,则需用到onPageNotFound()方法。
该方法从基础库1.9.90开始支持,低版本需要做兼容处理。当要打开的页面并不存在时,会回调这个方法并带有3个参数,具体参数内容如表3-4所示。
表3-4 onPageNotFound()方法的参数
字 段
类 型
说 明
path
String
不存在页面的路径
query
Object
打开不存在页面的query
isEntryPage
Boolean
是否为本次启动的首个页面(例如从分享等入口进来,首个页面是开发者配置的分享页面)
onPageNotFound()方法的示例代码如下:
1. App({
2. onPageNotFound: function(res) {
3. //小程序打开的页面不存在时需要执行的代码
4. wx.redirectTo({
5. url: 'pages/test/test'
6. }) //如果是tabBar页面,请使用wx.switchTab
7. }
8. })
上述代码可以用指定的页面代替原生模板页面。需要注意的是,如果 onPageNotFound() 回调中又重定向到另一个不存在的页面,将重定向到微信自带的原生模板页面提示页面不存在,并且不再触发onPageNotFound()监听。
getApp()方法
在小程序的其他JS文件中均可以使用全局的getApp()方法获取小程序实例。
例如,test.js,示例代码如下:
1. var app=getApp()
2. console.log(app.globalData.userInfo)
此时,就可以在test.js页面获得app.js中保存的公共数据,并在console控制台打印输出。
需要注意的是,用户不可以在app.js的App()函数内部调用getApp()方法,可以直接使用关键字this代替。例如:
1. App({
2. globalData: {
3. userInfo: null //这是一个全局变量
4. }
5. onLoad:function(options){
6. console.log(this.globalData.userInfo) //使用this关键字获得全局变量
7. }
8. })
上述代码就在onLoad()方法中直接使用了this关键字获得全局变量。
3.1.2 注册页面
小程序在每个页面JS文件中通过使用Page(OBJECT)方法进行页面注册,该方法可以用于指定小程序页面的生命周期函数。Page()方法的OBJECT参数如表3-5所示。
表3-5 Page()方法的OBJECT参数
属 性
类 型
说 明
data
Object
页面的初始数据
onLoad()
Function
生命周期函数——监听页面的加载
onReady()
Function
生命周期函数——监听页面初次渲染完成
onShow()
Function
生命周期函数——监听页面的显示
onHide()
Function
生命周期函数——监听页面的隐藏
onUnload()
Function
生命周期函数——监听页面的卸载
onPullDownRefresh()
Function
页面相关事件处理函数——监听用户下拉动作
onReachBottom()
Function
页面上拉触底事件的处理函数
onShareAppMessage()
Function
用户单击右上角转发
onPageScroll()
Function
页面滚动触发事件的处理函数
onTabItemTap()
Function
若当前是tab页,单击tab时触发
其他
Any
开发者可以添加任意函数或数据到OBJECT参数中,在页面的函数中用?this?可以访问
注意:Page()方法只能写在小程序每个页面对应的JS文件中,并且每个页面只能注册1个。
在微信web开发者工具中新建页面时会自动生成页面JS文件的Page()方法。这里以test页面为例,创建完成后test.js的代码如下:
1. // pages/test/test.js
2. Page({
3. /**
4. * 页面的初始数据
5. */
6. data: {
7.
8. },
9. /**
10. * 生命周期函数——监听页面的加载
11. */
12. onLoad: function(options) {
13.
14. },
15. /**
16. * 生命周期函数——监听页面初次渲染完成
17. */
18. onReady: function() {
19.
20. },
21. /**
22. * 生命周期函数——监听页面的显示
23. */
24. onShow: function() {
25.
26. },
27. /**
28. * 生命周期函数——监听页面的隐藏
29. */
30. onHide: function() {
31.
32. },
33. /**
34. * 生命周期函数——监听页面的卸载
35. */
36. onUnload: function() {
37.
38. },
39. /**
40. * 页面相关事件处理函数——监听用户下拉动作
41. */
42. onPullDownRefresh: function() {
43.
44. },
45. /**
46. * 页面上拉触底事件的处理函数
47. */
48. onReachBottom: function() {
49.
50. },
51. /**
52. * 用户单击右上角分享
53. */
54. onShareAppMessage: function() {
55.
56. }
57.})
与App()方法的函数情况类似,开发者同样可以根据实际情况删除Page()中不需要的函数,或者保留该函数内部为空白。
除了函数外,Page()同样也支持添加自定义的页面变量,示例代码如下:
1. Page({
2. myData: '123', //定义页面变量
3. onLoad: function(options) {
4. console.log(this.myData) //使用this关键字调用页面变量
5. },
6. })
这里,变量的名称、取值和数量也都可以由开发者自定义。
初始数据
在Page()方法中默认生成的第一项就是data属性,该属性是页面第一次渲染使用的初始数据。当页面加载时,data将会以JSON字符串的形式由逻辑层传至渲染层,因此data中的数据必须是可以转成JSON的类型,例如字符串、数字、布尔值、对象、数组。渲染层可以通过WXML对数据进行绑定。
例如在data中放置两个自定义数据,页面JS文件的示例代码如下:
1. Page({
2. data:{
3. msg01: 'Hello',
4. msg02: 2018
5. }
6. })
对应WXML的示例代码如下:
{{msg01}} {{msg02}}
此时{{msg01}}和{{msg02}}不会显示字面内容,而是会查找data中的初始数据,然后显示出“Hello 2018”字样。
生命周期回调函数
Page()函数中默认生成的onLoad()、onShow()、onReady()、onHide()以及onUnload()均属于页面的生命周期回调函数,具体说明如下。
* onLoad():格式为onLoad(Object query),只在页面加载时触发一次,可以在onLoad()的参数中获取打开当前页面路径附带的参数。
* onShow():当页面显示或从小程序后台切入前台时触发。
* onReady():当页面初次渲染完成时触发。注意,一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
* onHide():当页面隐藏/切入后台时触发。例如navigateTo或底部tab切换到其他页面,小程序切入后台等。
* onUnload():当页面卸载时触发。例如redirectTo或navigateBack到其他页面时。
页面事件处理函数
Page()方法中默认生成的onPullDownRefresh()、onReachBottom()、onShareAppMessage()以及未自动生成的onPageScroll()、onTabItemTap()均属于页面事件处理函数,具体说明如下。
* onPullDownRefresh():监听用户下拉刷新事件,需要在app.json的window选项中或页面配置中开启enablePullDownRefresh。
* onReachBottom():监听用户上拉触底事件,可以在app.json的window选项中或页面配置中设置触发距离onReachBottomDistance。在触发距离内滑动期间,本事件只会被触发一次。
* onPageScroll(OBJECT):监听用户滑动页面事件。其参数OBJECT具有唯一属性scrollTop,该属性为Number类型,表示页面在垂直方向已滚动的距离(单位为px)。
* onShareAppMessage(OBJECT):监听用户单击页面内“转发”按钮(