目录结构
上图是我建立的的微信小程序的目录结构
主体学习
逻辑层(App Service)
小程序开发框架的逻辑层由 JavaScript 编写。
逻辑层将数据进行处理后发送给视图层,同时接受视图层的事件反馈。
在JavaScript 的基础上,我们做了一些修改,以方便地开发小程序。
¤ 增加App
和Page
方法,进行程序和页面的注册。
¤ 增加getApp
和getCurrentPages
方法,分别用来获取 App 实例和当前页面栈。
¤ 提供丰富的API,如微信用户数据,扫一扫,支付等微信特有能力。
¤ 每个页面有独立的作用域,并提供模块化能力。
¤ 由于框架并非运行在浏览器中,所以JavaScript 在 web 中一些能力都无法使用,如document
,window
等。
¤ 开发者写的所有代码最终将会打包成一份JavaScript
,并在小程序启动的时候运行,直到小程序销毁。类似 ServiceWorker,所以逻辑层也称之为 App Service。
app.js
是否必须存在 是
功能 小程序逻辑
app.js 总的来说实现了一个App()的函数
先说明下对于App()的注意事项,其实也是官方的
- App()必须在app.js中注册,且不能注册多个,其实我感觉app.js就像是一个网站基本的js文件,全站级的,而且随着之后的讲解我们就会明白为什么不能注册多个
- 不要在定义于App()内的函数调用getApp()(友情提示这个是用于获取App()对象的), 使用this即可,这个也没什么说的,this对于有一定的面向对象语言功底的(java(因为我是学这个的))或者有js基础的都不难理解
- 不要再 onLaunch( ) 的时候调用 getCurrentPages(), 此时page还没有生成,在我测试了这个方法后,大致明白了, 这个方法其实就是用于获取当前已经创建的页面,所以说想想onLaunch是什么时候调用的,就大致明白了
- 通过getApp() 获取实例后, 不要私自调用生命周期函数,额,这个是肯定的,一般情况下,你要是想要达到某个目的大不了再多写个函数不就ok了何必挑战极限
注意事项完了我们再来看看这个App()函数,官方文档上是这么说的
App() 函数用来注册一个小程序。接受一个 object 参数,其指定小程序的生命周期函数等。
但是我们对于object参数并不是很了解啊, object难道和 java的Object 一样是个基类?
之后我就看到了官方文档上对于object参数的说明
因为一些原因我直接上了截图
然后我们就明白了,其实是不一样的, object 其实更像是一个函数对象, 只不过微信官方会调这个参数的五个方法(我就看到了五个), onLaunch, onShow,onHide,onError,onPageNotFound, 他们分别是五个监听函数.
然后我结合着我的理解对这几个方法做下解释, 或者照着打一遍
首先我感觉得强调一下前后台的定义
这个是我的理解
前台后台,其实玩过手机应该都会知道一点,所谓的前台其实就是目前显示在我们显示屏上的 app/小程序,后台的话..就是在后台运行的程序,比如你现在在聊qq,比如你在用的时候,这时候qq是在前台的,假如你因为某件事情,切出了qq,那么这时你的qq就是在后台运行, 不知道说明白了没.
下面的是微信官方的解释
前台、后台定义:
当用户点击左上角关闭,或者按了设备 Home键离开微信,小程序并没有直接销毁,而是进入了后台;当再次进入微信或再次打开小程序,又会从后台进入前台。需要注意的是:只有当小程序进入后台一定时间,或者系统资源占用过高,才会被真正的销毁。
当然建议没事看下官方的文档,因为有时一些情况是会更新的
好了到此我们就明白了前后台了之后就可以解释这五个方法
onLaunch()
onLaunch 方法 小程序只会在初始化时调用且全局只调用一次, 我给个不是很准确的说法: 应该是在小程序每次从退出(即你把小程序关掉)到打开时调用的,想要再次调用?可以,关了小程序或者退出微信,再打开就可以再调一次.
在我们写小程序是的体现就是,当我们点击编译按钮时,会执行下我们的onLaunch方法, 下图为示例,在我点击编译后控制台打印了 初始化,而且在我点击切后台的按钮时并没有再次打印.
onShow()
onShow()方法就是在小程序在被调到前台时(包括小程序被启动) 触发的方法,就是每次小程序展示在我们面前,供我们使用时,被调用一次.
gif 图不是很清,但是表明了我的想法
onHide()
onHide()就是在程序由前台进入后台时调用的,如下图所示
onError()
即当小程序发生脚本错误时调用的方法, 这个怎么说呢, 其实我们也看出来了,微信小程序其实用的就是js代码,js代码在我们使用时因为编码的人的原因或者因为当时思考不全的原因,会发生一些错误,而这时我们的onError()就有用了,他发出了怒吼,发下你的错误我来背,如下图是我做的两次测试
第一次测试
第二次测试
如上图就是我的两次测试也许有人会问,我去干嘛做两次测试,那是因为我在做第一次测试时发现了一些问题, 第一次测试时我把onHide()强行人工调坏,但是当这个错误第一次出现后我们发现onError调用了,但第二次的时候并没有调用,然后给了我一种错觉是不是一个地方的错误只会调用一次onError()方法,,这个也太不科学了吧, 没道理啊, 之后我就再次把onShow(),也调坏了, 之后就像动态图上的一样, 不管怎么反复的让这两个位置报错,每次onError()都会出现,而且我们发现也是符合show,hide的交替出现,不过幸亏的是这个error应该不会再一个地方连续触发的(应该吧)… , 毕竟我们不会发一个一直抛错的程序上去, 那就没意思了
onPageNotFound()
这个我也很纳闷我就是用不了不管是使用没有id的还是使用有id的就是用不了就是感觉很神奇,所以对他我也没有太多的解释,但是其实他就是为了解决404而出现的
好了关于app.js基本的情况就到这里了
下面是我的app.js的代码
//app.js
App({
//页面找不到时调用,但是没体会到用处
onPageNotFound: function (path){
console.info("找不到页面");
},
//当发生错误时调用
onError : function(){
console.error("发生了一些错误");
},
//当微信小程序转入后台时调用
onHide : function(){
console.info("我藏起来了");
},
//当微信小程序转入前台时调用
onShow : function(){
//在控制台打印一句话
console.info("我回来啦");
},
//打开微信小程序时调用, 请注意是打开不是唤醒
onLaunch: function () {
//在控制台打印一句话
console.info("初始化");
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
}
})
// 获取用户信息
wx.getSetting({
success: res => {
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
this.userInfoReadyCallback(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null
}
})