微信小程序学习((二)app.js及index.js详解)

微信小程序学习:(二)app.js及index.js详解 项目地址:https://github.com/leoricding/-
在用ide创建小程序项目时,系统默认为我们创建了一个helloword的样例模板:包括查询用户设置、获取用户信息、返回用户名及头像、页面跳转等。下面我就一一解析: 1、app.js 这是小程序的入口,启动小程序时首先调用app.js。 App()注册小程序,然后内部按生命周期执行。

//app.js //注册小程序 App({ onLaunch: function () { console.log("app.js初始化")// 展示本地存储能力 // 往本地存储写入log数据,登录日志 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs)// 登录 // 用户登录小程序 wx.login({ success: res => { // 登录成功后的回调 // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log('wx.login登录成功') } }) // 重点在这 // 获取用户的设置,返回用户的授权信息 // 判断用户是否授权,若已经授权,调用wx.getUserInfo接口获取用户信息, // 将获取的信息存到全局状态this.globalData.userInfo // 若用户未授权,直接逃过,进入index页面 wx.getSetting({ success: res => {// 获取成功的回调 console.log('获取用户的当前设置,返回授权后的信息') console.log(res)//判断用户是否授权 if (res.authSetting['scope.userInfo']) { // 已经授权,则无需重复授权 // 可以直接调用 wx.getUserInfo 获取用户信息,不会弹框 console.log("用户已经授权") wx.getUserInfo({ success: res => { // 获取用户信息成功后的回调 // 可以将 res 发送给后台解码出 unionId // 将用户信息赋值给this.globalData.userInfo this.globalData.userInfo = res.userInfo console.log('app.js中获取用户信息成功') console.log(this.globalData.userInfo)// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 // app.userInfoReadyCallback是在index的onLoad函数中定义的 // 判断userInfoReadyCallback这个属性是否存在 // 如果存在,则执行,将用户数据赋值给globalData及index中的data if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) }, // 全局状态 globalData: { userInfo: null } })

(1)在onLoad函数中,首先将小程序的登录日志写入到本地。
每加载一次小程序,就写入一次。
// 展示本地存储能力 // 往本地存储写入log数据,登录日志 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs)

(2)小程序登录。
调用wx.login接口,换取 openId, sessionKey, unionId
有后端API才有用,这里没有后端,所以只打印了一下
// 登录 // 用户登录小程序 wx.login({ success: res => { // 登录成功后的回调 // 发送 res.code 到后台换取 openId, sessionKey, unionId console.log('wx.login登录成功') } })

(3)读取用户信息。
wx.getSetting()获取用户设置(返回用户的已授权信息)
若已授权(res.authSetting[‘scope.userInfo’]存在),通过wx.getUserInfo调用用户信息。调用成功后,写入全局状态this.globalData.userInfo,然后index页面中通过onLoad函数调用globalData.userInfo,在index页面显示用户信息。
// 重点在这 // 获取用户的设置,返回用户的已授权信息 // 判断用户是否授权,若已经授权,调用wx.getUserInfo接口获取用户信息, // 将获取的信息存到全局状态this.globalData.userInfo // 若用户未授权,直接逃过,进入index页面 wx.getSetting({ success: res => {// 获取成功的回调 console.log('获取用户的当前设置,返回授权后的信息') console.log(res)//判断用户是否授权 if (res.authSetting['scope.userInfo']) { // 已经授权,则无需重复授权 // 可以直接调用 wx.getUserInfo 获取用户信息,不会弹框 console.log("用户已经授权") wx.getUserInfo({ success: res => { // 获取用户信息成功后的回调 // 可以将 res 发送给后台解码出 unionId // 将用户信息赋值给this.globalData.userInfo this.globalData.userInfo = res.userInfo console.log('app.js中获取用户信息成功') console.log(this.globalData.userInfo)// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 // app.userInfoReadyCallback是在index的onLoad函数中定义的 // 判断userInfoReadyCallback这个属性是否存在 // 如果存在,则执行,将用户数据赋值给globalData及index中的data if (this.userInfoReadyCallback) { this.userInfoReadyCallback(res) } } }) } } }) },

但这里有一个问题,如果index页面加载完了,wx.getUserInfo才返回数据怎么办? 因为wx.getUserInfo是通过网络异步获取用户数据,无法保证一定在index页面加载之前就能获取到啊。 这里就用了userInfoReadyCallback函数,这个函数是在index的onLoad函数定义的。
app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) }

就是一个简单的赋值函数,将res赋值给index中的data。 而在app.js中的wx.getUserInfo中判断app.userInfoReadyCallback是否存在,如果存在,那么就说明index中的onload函数已经为app写入了userInfoReadyCallback方法,也就是说wx.getUserInfo是通过网络异步获取用户数据成功,实在index加载数据之后,这时就需要调用这个方法,将wx.getUserInfo的返回信息,写入到index中的data。 2、index.js
// index.js // 获取应用实例 // 用于调用全局状态app.globalData const app = getApp()// 注册当前页面index Page({ data: { motto: 'Hello ', userInfo: {}, hasUserInfo: false, // 用于判断微信是否支持button.open-type.getUserInfo用法 canIUse: wx.canIUse('button.open-type.getUserInfo') },// 生命周期函数,页面加载时 onLoad: function () { console.log('index.js初始化')// 判断是否已经获取到用户信息 if (app.globalData.userInfo) { // 已经获取用户信息 // 将用户信息赋值给userInfo // 将hasUserInfo设置为true this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) console.log("写入data数据成功") this.routerGo() } else if (this.data.canIUse){ // 未获取到用户信息,但微信支持button.open-type.getUserInfo用法 // 定义app.userInfoReadyCallback函数, // 这个函数在app.js调用 // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 微信不支持button.open-type.getUserInfo用法 // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } },// 绑定自定义点击事件getUserInfo // 获取用户信息 // 回调函数,e就是用户授权后的返回值 // 若用户授权,用户信息保存在e.detail.userInfo // 若用户拒绝,e.detail.userInfo为undefined getUserInfo: function(e) { console.log("index按钮点击了,调用用户信息") console.log(e) console.log(e.detail.userInfo) // 将用户信息 app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) this.routerGo() },// 事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) },// 实现页面自动跳转 routerGo(){ console.log('跳转函数调用了')// 定义一个周期函数interval // 判断image图片是否渲染,渲染成功后自动跳转 let interval=setInterval( ()=> { if (wx.createSelectorQuery().select('image')) { console.log(wx.createSelectorQuery().select('image')) // 跳转 // 跳转成功后执行回调函数clearInterval wx.navigateTo({ url: './../lession/lession', success:()=>{ console.log(this) clearInterval(interval) }, }) } }, 500) } })

(1)获取全局应用app
这样可以通过app.globalData.userInfo获取全局状态。
// index.js // 获取应用实例 // 用于调用全局状态app.globalData const app = getApp()

(2)通过Page()注册当前页面。
(3)其中data是index页面的数据
data: { motto: 'Hello ', userInfo: {}, hasUserInfo: false, // 用于判断微信是否支持button.open-type.getUserInfo用法 canIUse: wx.canIUse('button.open-type.getUserInfo') },

(4)然后执行onLoad生命周期函数。
? 看着复制,其实逻辑很简单。
条件一:判断app.globalData.userInfo中有信息,写入data。 this.routerGo()是我自己写的页面跳转函数,自动跳转到下一个页面。可忽略。
条件二:判断app.globalData.userInfo中没有信息&&微信版本支持button.open-type.getUserInfo(this.data.canIUse)获取用户信息的方式,那么就是说wx.getUserInfo是网络请求,可能会在 Page.onLoad 之后才返回,所以定义app.userInfoReadyCallback方法,在wx.getUserInfo的成功回调中执行。 条件三:判断app.globalData.userInfo中没有信息&&微信版本不支持,那么直接调用wx.getUserInfo()接口。 onLoad函数执行完毕。
// 生命周期函数,页面加载时 onLoad: function () { console.log('index.js初始化')// 判断是否已经获取到用户信息 if (app.globalData.userInfo) { // 已经获取用户信息 // 将用户信息赋值给userInfo // 将hasUserInfo设置为true this.setData({ userInfo: app.globalData.userInfo, hasUserInfo: true }) console.log("写入data数据成功") this.routerGo() } else if (this.data.canIUse){ // 未获取到用户信息,但微信支持button.open-type.getUserInfo用法 // 定义app.userInfoReadyCallback函数, // 这个函数在app.js调用 // 由于 wx.getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 // 所以此处加入 callback 以防止这种情况 app.userInfoReadyCallback = res => { this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } } else { // 微信不支持button.open-type.getUserInfo用法 // 在没有 open-type=getUserInfo 版本的兼容处理 wx.getUserInfo({ success: res => { app.globalData.userInfo = res.userInfo this.setData({ userInfo: res.userInfo, hasUserInfo: true }) } }) } },

(5)绑定捕获事件。
// 事件处理函数 bindViewTap: function() { wx.navigateTo({ url: '../logs/logs' }) },// 绑定自定义点击事件getUserInfo // 获取用户信息 // 回调函数,e就是用户授权后的返回值 // 若用户授权,用户信息保存在e.detail.userInfo // 若用户拒绝,e.detail.userInfo为undefined getUserInfo: function(e) { console.log("index按钮点击了,调用用户信息") console.log(e) console.log(e.detail.userInfo) // 将用户信息 app.globalData.userInfo = e.detail.userInfo this.setData({ userInfo: e.detail.userInfo, hasUserInfo: true }) this.routerGo() },

【微信小程序学习((二)app.js及index.js详解)】(6)自定义方法,实现页面跳转。
routerGo(){ console.log('跳转函数调用了')// 定义一个周期函数interval // 判断image图片是否渲染,渲染成功后自动跳转 let interval=setInterval( ()=> { if (wx.createSelectorQuery().select('image')) { console.log(wx.createSelectorQuery().select('image')) // 跳转 // 跳转成功后执行回调函数clearInterval wx.navigateTo({ url: './../lession/lession', success:()=>{ console.log(this) clearInterval(interval) }, }) } }, 500) }

    推荐阅读