小程序:逻辑层

ylbtech-小程序:逻辑层

逻辑层(App Service)

小程序开发框架的逻辑层由 JavaScript 编写html

逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈node

在 JavaScript 的基础上,咱们作了一些修改,以方便地开发小程序。web

  • 增长 App 和 Page 方法,进行程序和页面的注册。
  • 增长 getApp 和 getCurrentPages 方法,分别用来获取 App 实例和当前页面栈。
  • 提供丰富的 API,如微信用户数据,扫一扫,支付等微信特有能力。
  • 每一个页面有独立的做用域,并提供模块化能力。
  • 因为框架并不是运行在浏览器中,因此 JavaScript 在 web 中一些能力都没法使用,如 documentwindow 等。
  • 开发者写的全部代码最终将会打包成一份 JavaScript,并在小程序启动的时候运行,直到小程序销毁。相似 ServiceWorker,因此逻辑层也称之为 App Service
1. 注册程序返回顶部

App

App()

App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。json

object参数说明:小程序

属性 类型 描述 触发时机
onLaunch Function 生命周期函数--监听小程序初始化 当小程序初始化完成时,会触发 onLaunch(全局只触发一次
onShow Function 生命周期函数--监听小程序显示 当小程序启动,或从后台进入前台显示,会触发 onShow
onHide Function 生命周期函数--监听小程序隐藏 当小程序从前台进入后台,会触发 onHide
onError Function 错误监听函数 当小程序发生脚本错误,或者 api 调用失败时,会触发 onError 并带上错误信息
其余 Any   开发者能够添加任意的函数或数据到 Object 参数中,用 this 能够访问

前台、后台定义: 当用户点击左上角关闭,或者按了设备 Home 键离开微信小程序并无直接销毁,而是进入了后台当再次进入微信或再次打开小程序,又会从后台进入前台。须要注意的是:只有当小程序进入后台必定时间,或者系统资源占用太高,才会被真正的销毁api

关闭小程序(基础库版本1.1.0开始支持): 当用户从扫一扫、转发等入口(场景值为1007, 1008, 1011, 1025)进入小程序,且没有置顶小程序的状况下退出,小程序会被销毁。数组

小程序运行机制在基础库版本 1.4.0 有所改变: 上一条关闭逻辑在新版本已不适用。详情浏览器

示例代码:微信

App({
  onLaunch: function(options) {
    // Do something initial when launch.
  },
  onShow: function(options) {
      // Do something when show.
  },
  onHide: function() {
      // Do something when hide.
  },
  onError: function(msg) {
    console.log(msg)
  },
  globalData: 'I am global data'
})

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时支持

场景值 详见app

如下场景支持返回 referrerInfo.appId:

场景值 场景 appId 信息含义
1020 公众号 profile 页相关小程序列表 返回来源公众号 appId
1035 公众号自定义菜单 返回来源公众号 appId
1036 App 分享消息卡片 返回来源应用 appId
1037 小程序打开小程序 返回来源小程序 appId
1038 从另外一个小程序返回 返回来源小程序 appId
1043 公众号模板消息 返回来源公众号 appId

getApp()

全局的 getApp() 函数能够用来获取到小程序实例。

// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data

 

注意:

  • App() 必须在 app.js 中注册,且不能注册多个。
  • 不要在定义于 App() 内的函数中调用 getApp() ,使用 this 就能够拿到 app 实例。
  • 不要在 onLaunch 的时候调用 getCurrentPages(),此时 page 尚未生成。
  • 经过 getApp() 获取实例以后,不要私自调用生命周期函数。
2. 场景值返回顶部

场景值

基础库 1.1.0 开始支持,低版本需作兼容处理

当前支持的场景值有:

场景值ID 说明
1001 发现栏小程序主入口
1005 顶部搜索框的搜索结果页
1006 发现栏小程序主入口搜索框的搜索结果页
1007 单人聊天会话中的小程序消息卡片
1008 群聊会话中的小程序消息卡片
1011 扫描二维码
1012 长按图片识别二维码
1013 手机相册选取二维码
1014 小程序模版消息
1017 前往体验版的入口页
1019 微信钱包
1020 公众号 profile 页相关小程序列表
1022 聊天顶部置顶小程序入口
1023 安卓系统桌面图标
1024 小程序 profile 页
1025 扫描一维码
1026 附近小程序列表
1027 顶部搜索框搜索结果页“使用过的小程序”列表
1028 个人卡包
1029 卡券详情页
1030 自动化测试下打开小程序
1031 长按图片识别一维码
1032 手机相册选取一维码
1034 微信支付完成页
1035 公众号自定义菜单
1036 App 分享消息卡片
1037 小程序打开小程序
1038 从另外一个小程序返回
1039 摇电视
1042 添加好友搜索框的搜索结果页
1043 公众号模板消息
1044 带 shareTicket 的小程序消息卡片(详情)
1047 扫描小程序码
1048 长按图片识别小程序码
1049 手机相册选取小程序码
1052 卡券的适用门店列表
1053 搜一搜的结果页
1054 顶部搜索框小程序快捷入口
1056 音乐播放器菜单
1058 公众号文章
1059 体验版小程序绑定邀请页
1064 微信连Wifi状态栏
1067 公众号文章广告
1068 附近小程序列表广告
1072 二维码收款页面
1073 客服消息列表下发的小程序消息卡片
1074 公众号会话下发的小程序消息卡片

能够在 App 的 onlaunch 和 onshow 中获取上述场景值,部分场景值下还能够获取来源应用、公众号或小程序的appId。详见

Tip: 因为Android系统限制,目前还没法获取到按 Home 键退出到桌面,而后从桌面再次进小程序的场景值,对于这种状况,会保留上一次的场景值。

3. 注册页面返回顶部

Page

Page() 函数用来注册一个页面。接受一个 object 参数,其指定页面的初始数据、生命周期函数、事件处理函数等。

object 参数说明:

属性 类型 描述
data Object 页面的初始数据
onLoad Function 生命周期函数--监听页面加载
onReady Function 生命周期函数--监听页面初次渲染完成
onShow Function 生命周期函数--监听页面显示
onHide Function 生命周期函数--监听页面隐藏
onUnload Function 生命周期函数--监听页面卸载
onPullDownRefresh Function 页面相关事件处理函数--监听用户下拉动做
onReachBottom Function 页面上拉触底事件的处理函数
onShareAppMessage Function 用户点击右上角转发
onPageScroll Function 页面滚动触发事件的处理函数
其余 Any 开发者能够添加任意的函数或数据到 object 参数中,在页面的函数中用 this 能够访问

object 内容在页面加载时会进行一次深拷贝,需考虑数据大小对页面加载的开销

示例代码:

//index.js
Page({
  data: {
    text: "This is page data."
  },
  onLoad: function(options) {
    // Do some initialize when page load.
  },
  onReady: function() {
    // Do something when page ready.
  },
  onShow: function() {
    // Do something when page show.
  },
  onHide: function() {
    // Do something when page hide.
  },
  onUnload: function() {
    // Do something when page close.
  },
  onPullDownRefresh: function() {
    // Do something when pull down.
  },
  onReachBottom: function() {
    // Do something when page reach bottom.
  },
  onShareAppMessage: function () {
   // return custom share data when user share.
  },
  onPageScroll: function() {
    // Do something when page scroll
  },
  // Event handler.
  viewTap: function() {
    this.setData({
      text: 'Set some data for updating view.'
    }, function() {
      // this is setData callback
    })
  },
  customData: {
    hi: 'MINA'
  }
})

初始化数据

初始化数据将做为页面的第一次渲染。data 将会以 JSON 的形式由逻辑层传至渲染层,因此其数据必须是能够转成 JSON 的格式:字符串,数字,布尔值,对象,数组

渲染层能够经过 WXML 对数据进行绑定。

示例代码:

<view>{{text}}</view>
<view>{{array[0].msg}}</view>
Page({
  data: {
    text: 'init data',
    array: [{msg: '1'}, {msg: '2'}]
  }
})

生命周期函数

  • onLoad: 页面加载

    • 一个页面只会调用一次,能够在 onLoad 中获取打开当前页面所调用的 query 参数。
  • onShow: 页面显示

    • 每次打开页面都会调用一次。
  • onReady: 页面初次渲染完成

    • 一个页面只会调用一次,表明页面已经准备稳当,能够和视图层进行交互。
    • 对界面的设置如wx.setNavigationBarTitle请在onReady以后设置。详见生命周期
  • onHide: 页面隐藏

    • navigateTo或底部tab切换时调用。
  • onUnload: 页面卸载

    • redirectTonavigateBack的时候调用。

生命周期的调用以及页面的路由方式详见

onLoad参数

类型 说明
Object 其余页面打开当前页面所调用的 query 参数

页面相关事件处理函数

  • onPullDownRefresh: 下拉刷新

    • 监听用户下拉刷新事件。
    • 须要在app.jsonwindow选项中或页面配置中开启enablePullDownRefresh
    • 当处理完数据刷新后,wx.stopPullDownRefresh能够中止当前页面的下拉刷新。
  • onReachBottom: 上拉触底

    • 监听用户上拉触底事件。
    • 能够在app.jsonwindow选项中或页面配置中设置触发距离onReachBottomDistance
    • 在触发距离内滑动期间,本事件只会被触发一次。
  • onPageScroll: 页面滚动

    • 监听用户滑动页面事件。
    • 参数为 Object,包含如下字段:
字段 类型 说明
scrollTop Number 页面在垂直方向已滚动的距离(单位px)
  • onShareAppMessage: 用户转发
    • 只有定义了此事件处理函数,右上角菜单才会显示“转发”按钮
    • 用户点击转发按钮的时候会调用
    • 此事件须要 return 一个 Object,用于自定义转发内容

自定义转发字段

字段 说明 默认值
title 转发标题 当前小程序名称
path 转发路径 当前页面 path ,必须是以 / 开头的完整路径

示例代码

Page({
  onShareAppMessage: function () {
    return {
      title: '自定义转发标题',
      path: '/page/user?id=123'
    }
  }
})

事件处理函数

除了初始化数据和生命周期函数,Page 中还能够定义一些特殊的函数:事件处理函数。在渲染层能够在组件中加入事件绑定,当达到触发事件时,就会执行 Page 中定义的事件处理函数。

示例代码:

<view bindtap="viewTap"> click me </view>
Page({
  viewTap: function() {
    console.log('view tap')
  }
})

Page.prototype.route

基础库 1.2.0 开始支持,低版本需作兼容处理

route 字段能够获取到当前页面的路径。

Page.prototype.setData()

setData 函数用于将数据从逻辑层发送到视图层(异步)同时改变对应的 this.data 的值(同步)

setData() 参数格式

字段 类型 必填 描述 最低版本
data Object 此次要改变的数据  
callback Function 回调函数 1.5.0

object 以 key,value 的形式表示将 this.data 中的 key 对应的值改变成 value。 callback 是一个回调函数,在此次setData对界面渲染完毕后调用。

其中 key 能够很是灵活,以数据路径的形式给出,如 array[2].messagea.b.c.d,而且不须要在 this.data 中预先定义。

注意:

  1. 直接修改 this.data 而不调用 this.setData 是没法改变页面的状态的,还会形成数据不一致。
  2. 单次设置的数据不能超过1024kB,请尽可能避免一次设置过多的数据。
  3. 请不要把 data 中任何一项的 value 设为 undefined ,不然这一项将不被设置并可能遗留一些潜在问题。

示例代码:

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap="changeText"> Change normal data </button>
<view>{{num}}</view>
<button bindtap="changeNum"> Change normal num </button>
<view>{{array[0].text}}</view>
<button bindtap="changeItemInArray"> Change Array data </button>
<view>{{object.text}}</view>
<button bindtap="changeItemInObject"> Change Object data </button>
<view>{{newField.text}}</view>
<button bindtap="addNewField"> Add new data </button>

 

//index.js
Page({
  data: {
    text: 'init data',
    num: 0,
    array: [{text: 'init data'}],
    object: {
      text: 'init data'
    }
  },
  changeText: function() {
    // this.data.text = 'changed data'  // bad, it can not work
    this.setData({
      text: 'changed data'
    })
  },
  changeNum: function() {
    this.data.num = 1
    this.setData({
      num: this.data.num
    })
  },
  changeItemInArray: function() {
    // you can use this way to modify a danamic data path
    this.setData({
      'array[0].text':'changed data'
    })
  },
  changeItemInObject: function(){
    this.setData({
      'object.text': 'changed data'
    });
  },
  addNewField: function() {
    this.setData({
      'newField.text': 'new data'
    })
  }
}) 
如下内容你不须要立马彻底弄明白,不过之后它会有帮助。

生命周期

下图说明了 Page 实例的生命周期。

4. 页面路由返回顶部

页面路由

在小程序中全部页面路由所有由框架进行管理。

页面栈

框架以栈的形式维护了当前的全部页面。 当发生路由切换的时候,页面栈的表现以下:

路由方式 页面栈表现
初始化 新页面入栈
打开新页面 新页面入栈
页面重定向 当前页面出栈,新页面入栈
页面返回 页面不断出栈,直到目标返回页,新页面入栈
Tab 切换 页面所有出栈,只留下新的 Tab 页面
重加载 页面所有出栈,只留下新的页面

getCurrentPages()

getCurrentPages() 函数用于获取当前页面栈的实例,以数组形式按栈的顺序给出第一个元素为首页最后一个元素为当前页面

Tip:不要尝试修改页面栈,会致使路由以及页面状态错误。

路由方式

对于路由的触发方式以及页面生命周期函数以下:

路由方式 触发时机 路由前页面 路由后页面
初始化 小程序打开的第一个页面   onLoad, onShow
打开新页面 调用 API wx.navigateTo 或使用组件 <navigator open-type="navigateTo"/> onHide onLoad, onShow
页面重定向 调用 API wx.redirectTo 或使用组件 <navigator open-type="redirectTo"/> onUnload onLoad, onShow
页面返回 调用 API wx.navigateBack 或使用组件<navigator open-type="navigateBack">或用户按左上角返回按钮 onUnload onShow
Tab 切换 调用 API wx.switchTab 或使用组件 <navigator open-type="switchTab"/> 或用户切换 Tab   各类状况请参考下表
重启动 调用 API wx.reLaunch 或使用组件 <navigator open-type="reLaunch"/> onUnload onLoad, onShow

Tab 切换对应的生命周期(以 A、B 页面为 Tabbar 页面,C 是从 A 页面打开的页面,D 页面是从 C 页面打开的页面为例):

当前页面 路由后页面 触发的生命周期(按顺序)
A A Nothing happend
A B A.onHide(), B.onLoad(), B.onShow()
A B(再次打开) A.onHide(), B.onShow()
C A C.onUnload(), A.onShow()
C B C.onUnload(), B.onLoad(), B.onShow()
D B D.onUnload(), C.onUnload(), B.onLoad(), B.onShow()
D(从转发进入) A D.onUnload(), A.onLoad(), A.onShow()
D(从转发进入) B D.onUnload(), B.onLoad(), B.onShow()

Tips:

  • navigateToredirectTo 只能打开非 tabBar 页面
  • switchTab 只能打开 tabBar 页面
  • reLaunch 能够打开任意页面
  • 页面底部的 tabBar 由页面决定,即只要是定义为 tabBar 的页面,底部都有 tabBar。
  • 调用页面路由带的参数能够在目标页面的onLoad中获取
5. 模块化返回顶部

文件做用域

JavaScript 文件中声明的变量和函数只在该文件中有效不一样的文件中能够声明相同名字的变量和函数,不会互相影响

经过全局函数 getApp() 能够获取全局的应用实例,若是须要全局的数据能够在 App() 中设置,如:

// app.js
App({
  globalData: 1
})
// a.js
// The localValue can only be used in file a.js.
var localValue = 'a'
// Get the app instance.
var app = getApp()
// Get the global data and change it.
app.globalData++
// b.js
// You can redefine localValue in file b.js, without interference with the localValue in a.js.
var localValue = 'b'
// If a.js it run before b.js, now the globalData shoule be 2.
console.log(getApp().globalData)

 

模块化

能够将一些公共的代码抽离成为一个单独的 js 文件,做为一个模块。模块只有经过 module.exports 或者 exports 才能对外暴露接口

须要注意的是:

  • exports 是 module.exports 的一个引用,所以在模块里边随意更改 exports 的指向会形成未知的错误。因此更推荐开发者采用 module.exports 来暴露模块接口,除非你已经清晰知道这二者的关系。
  • 小程序目前不支持直接引入 node_modules , 开发者须要使用到 node_modules 时候建议拷贝出相关的代码到小程序的目录中。
// common.js
function sayHello(name) {
  console.log(`Hello ${name} !`)
}
function sayGoodbye(name) {
  console.log(`Goodbye ${name} !`)
}

module.exports.sayHello = sayHello
exports.sayGoodbye = sayGoodbye

​在须要使用这些模块的文件中,使用 require(path) 将公共代码引入

var common = require('common.js')
Page({
  helloMINA: function() {
    common.sayHello('MINA')
  },
  goodbyeMINA: function() {
    common.sayGoodbye('MINA')
  }
})

Tips

  1. tip: require 暂时不支持绝对路径

 

6. API返回顶部

小程序开发框架提供丰富的微信原生 API,能够方便的调起微信提供的能力,如获取用户信息,本地存储,支付功能等。

详细介绍请参考 API 文档

7.返回顶部
 
8.返回顶部
 
9.返回顶部
 
10.返回顶部
一、
二、
 
11.返回顶部
 
warn 做者:ylbtech
出处:http://ylbtech.cnblogs.com/
本文版权归做者和博客园共有,欢迎转载,但未经做者赞成必须保留此段声明,且在文章页面明显位置给出原文链接,不然保留追究法律责任的权利。
相关文章
相关标签/搜索