作者也是刚开始接触小程序开发,不足之处请指正。
先看工程目录,index、logs、mine、wallet这几个文件夹可以看做一个个页面,每个文件夹(页面)里有四个文件:.js .json .wxml .wxss
.js文件就是JavaScript,写逻辑相关的代码
.json文件做一些固定的配置
.wxml类似于html写控件
.wxss类似于css 写控件的样式
具体来看
创建一个小程序项目会默认有app.js,app.json,app.wxss这三个文件作用于是整个小程序,而每个页面里的这几个文件的作用域是当前页面。
先来看官方默认创建的代码
//app.js
App({
onLaunch: function () {
// 展示本地存储能力
var logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
console.log('code',res)
}
})
// 获取用户信息
wx.getSetting({
success: res => {
console.log('setting',res.authSetting)
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallbacks) {
this.userInfoReadyCallbacks(res)
}
}
})
}
}
})
},
globalData: {
userInfo: null
}
})
onLaunch函数是小程序生命周期函数,监听小程序初始化。即小程序入口,通过查阅官方文档可以看到此函数的解释。
下面来分析 var logs = wx.getStorageSync('logs') || [],wx.调用的wx.getStorageSync一看就是微信官方API,这行代码是同步获取key为'logs'的缓存,且logs变量类型为数组。通过查阅官方API可以看到此函数的定义,同步获取缓存也就是会阻塞当前线程的意思喽,即获取完这个数组才会继续执行代码。
logs.unshift(Date.now())又是啥意思呢,查询微信官方API发现unshift方法是ES5标准里的,意思是在数组的最前面插入一个元素,这里是插入了当前时间戳。
wx.setStorageSync('logs', logs)从字面看就是同步保存这个被修改的数组到缓存中。
// 登录
wx.login({
success: res => {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
console.log('code',res)
}
})
这个wx.login是什么意思,wx.开头即微信提供的API,意思是调用了login接口获取登录凭证(code),调用成功即success会返回code,然后向我们自己的服务器请求换取openId, sessionKey, unionId这些信息,来进行登录操作。
// 获取用户信息
wx.getSetting({
success: res => {
console.log('setting',res.authSetting)
if (res.authSetting['scope.userInfo']) {
// 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框
wx.getUserInfo({
success: res => {
// 可以将 res 发送给后台解码出 unionId
this.globalData.userInfo = res.userInfo
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallbacks) {
this.userInfoReadyCallbacks(res)
}
}
})
}
}
})
wx.getSetting用来获取小程序已经向用户请求过的权限,返回形式是一个字典(key:value)形式,其中'scope.userInfo'就是获取用户信息的key,如果这项为true就是获取到用户信息的意思。
wx.getUserInfo用来获取用户信息,success就会返回用户信息
this.globalData.userInfo = res.userInfo,this类似于iOS开发中的self,globalData是自定义的一个全局变量,内部数据结构是有一个userInfo,用来全局保存用户信息。
this.userInfoReadyCallbacks又是个什么呢,类似于iOS开发中的block(闭包),函数名随便取,我就在后面加了个s, 用来异步反向传值,因为wx.getUserInfo这个接口是异步获取的,有可能会在index的js里的onLoad方法之后返回,如果index页面调用了userInfoReadyCallbacks来接收userInfo数据,则app.js里会执行this.userInfoReadyCallbacks(res),就可以异步给index页面传值了。
//index.js
app.userInfoReadyCallbacks = res => {
if (res.userInfo) {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
}
下面来看index.js文件
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')//固定写法 通过button获取用户信息只能这么写
},
//事件处理函数
bindViewTap: function () {//点击头像跳转logs页面
wx.navigateTo({
url: '../logs/logs'
})
},
onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse) {
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallbacks = res => {
if (res.userInfo) {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
}
} else {
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
if (res.userInfo) {
app.globalData.userInfo = res.userInfo
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
}
})
}
},
getUserInfoClick: function (e) {//点击了拒绝或同意后会回调
if (e.detail.userInfo) {
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
}
})
const app = getApp()获取应用实例,这样就可以使用全局变量了。
data: {
motto: '尬先生尬先生尬先生尬先生尬先生尬先生尬先生尬先生',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo')//固定写法 通过button获取用户信息只能这么写
},
定义了一个名为data的数据结构,有四个元素motoo是一个字符串,userInfo用户信息,hasUserInfo是否获取到了用户信息bool类型,canIUse判断小程序的API,回调,参数,组件等是否在当前版本可用,当前是判断button里获取用户信息在当前版本是否可用,'button.open-type.getUserInfo'就是通过button获取用户信息的固定写法。
bindViewTap: function () 是在index.wxml里绑定的头像image点击事件,即登录以后点击头像进行后续操作。
wx.navigateTo({
url: '../logs/logs'
})
wx.navigateTo保留当前页面,跳转到应用内的某个页面,url: '../logs/logs'即跳转到logs页面
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
}
如果在app.js页面获取userInfo速度快于index.js的onLoad方法,走这里。 this.setData给data赋值的同时会主动刷新index.wxml里的UI数据。
getUserInfoClick: function (e) {//点击了拒绝或同意后会回调
if (e.detail.userInfo) {
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
}
getUserInfoClick是在index.wxml里绑定的bindgetuserinfo="getUserInfoClick"即button的点击以后弹出的权限授权框的点击事件回调。
下面看下index.wxml文件
{{userInfo.nickName}}
{{motto}}
{{userInfo.nickName}}
{{userInfo.nickName}}包裹变量用两个花括号包装起来。