小程序开发框架的逻辑层是由JavaScript编写.
逻辑层将数据进行处理后发送给视图层,同时接收视图层的事件反馈.并在JS基础上增加了一些方法:
(1)增加App和Page方法,进行程序和页面注册
(2)增加getApp和getCurrentPages方法,分别用来获取App实例和当前页面栈.
(3)提供丰富API,如微信用户数据等.
(4)每个页面有独立作用域,并提供模块化能力
(5)由于框架并非运行在浏览器中,所以JS的一些如document和window等都不能使用
(6)开发者写的所有代码最终都会打包成一个JS,并在小程序启动时运行,直至小程序销毁,类似ServiceWorker,所以逻辑层也称之为AppService.
一.注册程序
1.APP
(1)APP()
APP()函数用来注册一个小程序.接收一个object参数,其指定小程序的生命周期函数等.
object参数说明:
1)onLaunch: 监听小程序初始化,当小程序初始化完成时,会触发onLaunch,全局只触发一次.
2)onShow: 监听小程序显示,当小程序启动,或者从后台进入前台显示时触发
3)onHide:监听小程序隐藏,当小程序从前台进入后台时,会触发onHide
4)onError:错误监听函数,当小程序发生脚本错误,或者api调用失败时,会触发onError并带上错误信息
5)其他: 开发者可以添加任意的函数或者数据到Object参数中,用this可以访问
前台后台定义:
当用户点击左上角关闭时,或者按了设备home键离开微信,小程序并没有直接销毁,而是进入后台,当再次进入微信或者再次进入小程序,又从后台进入前台
示例代码:
App({
onLaunch: function(){
},
onShow: function(){
},
onHide: function(){
},
onError: function(error){
console.log(error);
},
globalData = "w"
})
(2)getApp()
我们提供了全局的getApp()函数,可以获取到小程序实例.
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
注意:App()必须在app.js中注册,且不能注册多个.
不要在定义于App()内的函数中调用getApp(),使用this就能拿到实例
不要在onLaunch的时候调用getCurrentPage(),此时page还没生成.
二.注册页面
1.page
Page()函数用来注册一个页面,接收一个object参数,其指定页面的初始数据,生命周期函数,事件处理函数等.
object参数说明:
示例代码:
Page({
data: {
text: "This"
},
onLoad: function(options){
},
onReady: function(){
},
onShow: function(){
},
onHide: function(){
},
onUnload: function(){
},
onPullDownRefersh: function(){
},
})
2.初始化数据
初始化数据将作为页面的第一次渲染,data将会以JSON的形式由逻辑层传至渲染层,所以其数据必须是可以转成JSON格式:字符串,数字,布尔值,对象,数组.
渲染层可以通过WXML对数据进行绑定
<view>{{text}}view>
<view>{{array[0].msg}}view>
Page({
data: {
text: 'init data',
array: [{msg: '1'}, {msg: '2'}]
}
})
3.生命周期函数
onUnload:页面卸载,当redirectTo的时候调用
4.页面相关事件处理函数
onPullDownRefresh:下拉刷新
监听用户下拉刷新事件
需要在config的window选项中开启enablePullDownRefresh
当处理完数据刷新后,wx.stopPullDownRefresh可以停止当前页面的下拉刷新
自定义分享字段:
Page({
onShareAppMessage: function () {
return {
title: '自定义分享标题',
desc: '自定义分享描述',
path: '/page/user?id=123'
}
}
})
5.事件处理函数
(1)除了初始化数据和生命周期函数,Page中还可以定义一些特殊的函数:事件处理函数.在渲染层可以在组件中加入事件绑定,当触发事件时,就会执行page中定义的事件.
<view bindtap="viewTap">Click Meview>
Page({
viewTap: function()
{
console.log('view tap');
})
(2)Page.prototype.setData()
setData函数用于将数据从逻辑层发送到视图层,同时改变对应的this.data的值
注意:
直接修改this.data无效,无法改变页面状态,还会导致数据不一致.
单次设置的数据大小不能超过1024kb
1)setData参数格式
接收一个对象,以key,value的形式表示将this.data中的key对应的值改成value.
其中key可以非常灵活,以数据路径的形式给出,如array[2].message,a.b.c.d,并且不需要在this.data中预先定义.
示例:
<view>{{text}}view>
<button bindtap="changeText">Change normal databutton>
<view>{{array[0].text}}view>
<button bindtap = "changeItemArray">Change Array databutton>
<view>{{object.text}}view>
<button bindtap = "changeItemObject">Change Object
databutton>
<view>{{newField.text}}view>
<button bindtap = "addField">button>
//index.js
Page({
data: {
text: 'init data',
array: [{text: 'init data'}],
object:{
text: 'init data'
}
},
changeText: function(){
this.setData({
text: 'change data'
})
},
changeItemArray: function(){
this.setData({
'array[0]': 'change data'
})
},
changeItemInObject: function(){
this.setData({
'object.text': 'change data'
})
},
addNewField: function(){
this.setData({
'newField.text': 'new data'
})
}
})
(3)getCurrentPages()
getCurrentPages()函数用来获取当前页面栈实例, 以数组形式按栈顺序给出,第一个元素为首页,最后一个元素为当前页面.
注意:请不要尝试修改页面栈,会导致路由错误及状态页面错误.
1)页面栈
框架以栈的形式维护了当前所有的页面,当发生路由切换时,页面栈表现如下:
Tab切换:页面全部出栈,只留下新的Tab页面
2)生命周期
3)页面的路由
在小程序中所有的页面路由全部由框架进行管理,对于路由的触发形式以及页面生命周期函数如下:
Tab切换:调用wx.switchTab或者是使用组件navigator open-type=”switchTab”或者用户切换tab
4)Tab切换(以A,B页面为Tabbar页面,C是从A页面打开的页面,D是从C页面打开的页面为例)
A => B A.onHide() B.onLoad() B.onShow()
三.模块化
1.文件作用域
在JS文件中声明的变量和函数只在该文件中有效,不同的文件可以声明相同名字的变量和函数,不会互相影响.
通过全局函数getApp()可以获取全局的应用实例,如果需要全局的数据可以在App()中设置.如:
App({
globalData: 1
})
//a.js
var app = getApp();
app.globalData++; //获取全局变量并且改变他
//b.js
//如果a.js在b.js之前运行,这里会打印出2
console.log(getApp().globalData)
2.模块化
我们可以将一些公共的代码抽离成一个单独的js文件,作为一个模块.模块只有通过module.exports或者exports才能对外暴露接口
需要注意的是:
(1)exports是module.exports的一个引用,因此在模块里面随意更改exports的指向会造成未知的错误,所以我们推荐开发者采用module.exports来暴露块接口.
(2)小程序目前不支持 - 列表引入node_module,开发者需要使用到node_module时候建议拷贝出相关代码到小程序目录中
//common.js
function sayHello(name){
console.log(`Hello${name}!`);
}
function sayGoodye(name){
....
}
module.exports.sayHello = sayHello;
exports.sayGoodbye = sayGoodbye;
在需要使用这些模块的文件中,使用require(path)将公共代码引入
var common = require('common.js')
Page({
helloMina: function(){
common.sayHello('mina');
}
})