逻辑层,是事务逻辑处理的地方。对于小程序而言,逻辑层就是.js脚本文件的集合。逻辑层将数据进行处理后发送给视图层,同时接收视图层的事件反馈。
微信小程序开发框架的逻辑层是由JavaScript编写。在JavaScript的基础上,微信团队做了一些适当的修改,以便提高开发小程序的效率。主要修改包括:
♦ 增加app和page方法,进行程序和页面的注册
♦ 提供丰富的API,如扫一扫、支付等微信特有的能力
♦ 每个页面有独立的作用域,并提供模块化能力。
逻辑层的实现就是编写各个页面的.js脚本文件。但由于小程序并非运行在浏览器中,所以JavaScript在Web中的一些能力无法使用,如document、window等。
我们开发编写的所有代码最终会打包成一份JavaScript,并在小程序启动的时候运行,直到小程序销毁。
注册程序:App()方法
在逻辑层,App()方法用来注册一个小程序。App()接受一个object参数,用于指定小程序的生命周期函数等。App()方法有且仅有一个,存在于app.js中。object参数见下表
注意:onLaunch函数全局只触发一次。
前台、后台:用户当前界面运行或操作小程序时为前台;当用户点击左上角关闭,或者按了设备Home键离开微信,小程序并没有直接销毁,而是进入后台;当再次进入微信或再次打开小程序,又会从后台进入前台。
销毁:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正销毁。此时代表小程序的生命周期结束。
关闭小程序(公共库版本1.1.0开始支持): 当用户从扫一扫、转发等入口(场景值为1007, 1008, 1011, 1025)进入小程序,且没有置顶小程序的情况下退出,小程序会被销毁。
示例代码:
App({ onLaunch: function(){ //启动时执行的初始化工作 }, onShow: function(){ //小程序从后台进入前台时,触发执行的操作 }, onHide: function(){ //小程序从前台进入后台时,触发执行的操作 }, globalData:'I am global data' })
onLaunch, onShow 参数
获取更多转发信息
通常开发者希望转发出去的小程序被二次打开的时候能够获取到一些信息,例如群的标识。现在通过调用 wx.showShareMenu
并且设置 withShareTicket
为 true
,当用户将小程序转发到任一群聊之后,可以获取到此次转发的 shareTicket
,此转发卡片在群聊中被其他用户打开时,可以在 App.onLaunch() 获取到另一个 shareTicket
。这两步获取到的 shareTicket
均可通过 wx.getShareInfo() 接口可以获取到相同的转发信息。
微信团队为开发者提供全局的getApp()函数,可以用来获取小程序实例。示例如下:
//other.js var app = getApp(); console.log(app.globalData);//I am global data
注意: ♦ App()方法须在app.js中注册,且不能注册多个。 ♦ 不要再定义App()内的函数中调用getApp(),使用this就可以拿到App实例。
♦ 通过getApp()获取实例之后,不要私自调用生命周期函数。
注册页面:Page()方法
在逻辑层,Page()方法用来注册一个页面。Page()接受一个object参数,用于指定页面的初始数据、生命周期函数、事件处理函数等。Page()方法每个页面有且仅有一个,存在于该页面的.js文件中。
示例代码:
Page({ Data: { Text: 'This is page data.' }, onLoad: function (options) { //页面加载时执行的初始化工作 }, onReady: function () { //页面就绪后触发执行的操作 }, onShow: function () { //页面打开时,触发执行的操作 }, onHide: function () { //页面隐藏时,触发执行的操作 }, onUnload: function () { //页面关闭时,触发执行的操作 }, onPullDownRefresh: function(){ //用户在页面下拉时执行的操作 }, onReachBottom: function(){ //到达页面底部时执行的操作 }, //Event Handler viewTap: function () { this.setData({ text: 'set some data for updating view.' }) }, })
注意: ♦ 不要在 onLaunch 的时候调用 getCurrentPages(),此时 page 还没有生成。
初始化数据
初始化数据将作为页面的第一次渲染。对象data将会以JSON的形式由逻辑层传至视图层,所以其数据必须是可以转成JSON的格式:字符串、数字、布尔值、对象、数组。视图层可以通过WXML对数据进行绑定。
<!--demo.wxml--> <view>{{text}}</view> <view>{{array[0].msg}}</view>
//demo.js Page({ /** * 页面的初始数据 */ data: { text: 'init data', array: [{msg:'1'},{msg:'2'}] } })
页面的生命周期
生命周期包括onLoad、onShow、onReady、onHide、onUnload。
onload:页面加载时执行的初始化操作:
♦ 一个页面只会调用一次。
♦ 参数可以获取wx.navigateTo和wx.redirectTo及<navigator/>中的query。
onShow:页面显示时执行的操作。每次打开页面都会调用一次。
onReady:页面初次渲染完成时执行的操作。
♦ 一个页面只会调用一次,代表页面已经准备妥当,可以和视图层进行交互。
♦ 对页面的设置(如wx.setNavigationBarTitle)在onReady之后设置。
onHide:页面隐藏时执行的操作。当navigateTo或底部进行tab切换时调用。
onUnload:页面卸载时执行的操作。当进行redirectTo或navigateBack操作时调用。
页面相关事件处理函数
onPullDownRefresh:下拉刷新时执行的操作。
♦ 监听用户下拉刷新事件。
♦ 需要在config的window选项中开启enablePullDownRefresh。
♦ 处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新。
事件处理函数
除了初始化数据和生命周期函数,Page()方法中可以定义一些特殊的函数:事件处理函数。在视图层通过对组件加入事件绑定,当满足事件时,就会执行Page()中定义的事件处理函数。
//<!--wxml--> //绑定viwTap事件到view组件 <view bindtap="viewTap"> Click Me </view>
//page.js Page({ //定义一个viewTap事件处理函数 viewTap:function(){ console.log('view tap') } })
页面栈及其实例获取
框架以栈的形式维护了当前的所有页面。 当发生路由切换的时候,页面栈的表现如下:
getCurrentPages()函数用于获取当前页面栈的实例,以数组的形式按栈的顺序给出第一个元素为首页,最后一个元素为当前页面。
注:不要尝试修改页面栈,会导致路由以及页面状态错误。
页面的路由
在小程序中,所有页面的路由全部都由框架进行管理,对于路由的触发方式以及页面生命周期见下表:
Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例):
模块及调用
文件作用域
在页面的JavaScript(.js)脚本文件中声明的变量和函数只在该文件中有效;不同的文件中可以声明相同名字的变量和函数,不会相互影响。
通过全局函数getApp()可以获取全局的应用实例,如果需要全局的数据可以在App()中设置。
//app.js App({ globalData:1 }) //a.js //变量localValue只在a.js文件中有效 var localValue = 'a' //获取App实例 var app = getApp() //获取全局数据值并修改 app.globalData++ //b.js //可以在b.js文件中重新定义变量localValue,这并不会影响 a.js文件中的localValue var localValue = 'b' //若a.js在b.js之前运行,那么这里的globalData就应是2 console.log(getApp().globalData)
模块化
可以将一些公共的代码抽离成为一个单独的js脚本文件,作为一个模块。
注:模块只有通过module.exports才能对外暴露接口以供其他.js文件引入使用。
示例代码:
//common.js function sayHello(name){ console.log('Hello' + name + '!') } module.exports = { sayHello:sayHello }
在需要使用这些模块的.js文件中,使用require(path)将公共代码引入。
示例代码:
//call.js var common = require('common.js') Page({ helloMINA:function(){ common.sayHello('MINA') } })