我的知识记录分享
小程序用户登录和获取用户信息相对来说比较复杂,为了能够让大家可以更加直观的结合我们之前的知识来一步步探究到底是怎么一回事,建议大家重新新建一个****不使用云服务的小程序项目(沿用之前的叫法,叫模板小程序)。
使用开发者工具将app.js的代码修改为如下(可以把之前的全部删掉或注释掉,把下面代码复制粘贴过去)。了解一个函数一个API,实战方面从打印日志开始,而理论方面从技术文档开始。
function ()
模板小程序用的是箭头函数的写法,大家可以结合之前关于箭头函数的介绍、模板小程序的代码和上面的写法对照来学习。
从控制台可以看到wx.login返回的res对象里会包含errMsg和code,这个code是用户的登录凭证。
技术文档:获取用户登录凭证wx.login
而wx.getSetting返回的res对象里包含errMsg和用户当前的权限设置authSetting,包含是否允许获取用户信息,是否允许获取用户位置,是否允许使用手机相册等权限。我们可以根据打印的结果结合技术文档来深入理解。
如果要让小程序和自己的服务器账号打通,仅仅获取用户登录凭证是不够的,需要将这个code以及你的小程序appid和appSecret传回到你的开发服务器,然后在自己的服务器上调用auth.code2session接口,得到用户的openid和session_key。由于openid是当前用户的唯一标识,可以用来判断该用户是否已经在自己的服务器上注册过,如果注册过,则根据openid生成自定义登录态并返回给小程序,整个过程非常复杂。而由于云开发与微信登录鉴权无缝整合,这些内容都不会涉及,所以这里不多介绍。
我们要获取用户信息,首先需要判断用户是否允许,可以从authSetting对象里看scope.userInfo属性是否为true,如果为true,那我们可以调用wx.getUserInfo()接口来获取用户信息。
使用开发者工具给上面的wx.getSetting()函数添加内容,最终代码如下:
wx.getSetting({
success(res){ console.log('wx.getSetting得到的数据',res) if (res.authSetting["scope.userInfo"]){
wx.getUserInfo({
success(res){ console.log("wx.getUserInfo得到的数据",res)
}
})
}
}
})
由于scope.userInfo是一个属性名,无法使用点表示法res.authSetting.scope.userInfo来获取到它的值(会误认为是authSetting属性下的scope属性的usrInfo属性值),这里用到的是获取对象属性的另外一种表示方法,叫括号表示法,也就是用中括号[]围住属性名,属性名需用单引号或双引号围住。
在控制台console我们可以看到userInfo对象里包含着当前登录用户的昵称、头像、性别等信息。
但是这个数据是在app.js里,和我们之前接触到的数据都在页面的js里有所不同。而且用户信息的数据是所有页面都需要用到的,放在app.js里公用是应该的,但是我们要怎么才能调用到这个数据呢?
在上面的wx.getUserInfo的success回调函数里将获取到的userInfo对象赋值给globalData对象的userInfo属性。
wx.getUserInfo({
success(res){ console.log("wx.getUserInfo得到的数据",res) this.globalData.userInfo = res.userInfo
}
})
但是会提示 Cannot read property 'globalData' of undefined;
报错,但是模板小程序也是这样写代码的为什么却没有报错?这是因为箭头函数的this与非箭头函数this指向有不同。
this的指向情况非常复杂,尽管原理是“哪个对象调用函数,函数里面的this就指向哪个对象”,说起来非常简单,但是场景太多,大家在开发时不必强行理解,死记硬背,我们把this打印出来即可。比如我们可以将回调函数success的this打印出来,
success(res){ console.log('this是啥',this)
}
结果是this undefined
,并没有定义,和我们预计的是Page()函数对象并不一致,给它的this.globalData赋值当然会报错。
解决方法有两种,一种是模板小程序使用箭头函数,箭头函数继承的是外部对象的this,我们可以把代码wx.getSetting()里的success回调函数的写法都改为箭头函数的写法(这里要改两处,只改一个行不行?试试看),这时我们可以再来打印this,看看是什么情况。在控制台我们可以看到改为箭头函数之后的this的结果为一个pe对象,里面包含着Page()对象的生命周期函数和属性。
第二种方法是使用that指代,也就是在wx.getSetting()函数的前面写一行代码:
let that=this wx.getSetting({............}) //写这一行是为了便于你找位置
然后把wx.getUserInfo的success回调函数的改为如下:
res =>
由于情况复杂,this的指向经常会变,但是在this的指向还是Page()对象时,我们就把this赋值给that,这样就不会因为this指向变更而出现undefined了。
那我们如何在页面的js里调用globalData呢,这个时候就需要用到getApp()函数啦。
技术文档:getApp()
使用开发者工具新建一个user页面,然后在user.js的Page()函数前面添加如下代码:
let app = getApp() console.log('user页面打印的app', app) console.log('user页面打印的globalData', app.globalData.userInfo) console.log('user页面打印的tcbData',app.tcbData.eventInfo)
这样我们就能获取app.js里的globalData和自定义的属性了。
这里还会有一个问题,就是尽管我们已经获取到了globalData,我们也能在globalData.userInfo的打印日志里看到用户的信息,但是当我们想获取里面的值时,还是会报错,这是因为 wx.getUserInfo是异步获取的信息,这里涉及到的异步,我们之后会详细介绍。
在我们使用wx.getUserInfo的方式来获取用户信息时,控制台会报错: 获取 wx.getUserInfo 接口后续将不再出现授权弹窗,请注意升级。也就是小程序官方已经不建议开发者用wx.getUserInfo来获取用户信息,而是建议通过button的方式来获取,对用户的体验更好,也就是只有用户点击了按钮,用户信息才会被获取。
使用开发者工具在user.wxml里输入以下代码,这是一个button组件,要获取到用户信息,有两个必备条件,一是 open-type="getUserInfo",必须是这个值;二是绑定事件处理函数的属性名为bindgetuserinfo(类似于bindtap,但是属性名必须为bindgetuserinfo,至于事件处理函数的名称可以自定义)
<button open-type="getUserInfo" bindgetuserinfo="getUserInfomation"> 点击获取用户信息 </button>
这里的getUserInfomation和之前点击事件的事件处理函数是一致的,点击组件触发getUserInfomation,仍然会收到事件对象,我们把它打印出来,在user.js里添加以下代码:
function (event)
当我们点击“点击获取用户信息”的button按钮后,在控制台可以查看到getUserInfomation打印的事件对象,事件对象里有个detail属性,里面就有userInfo的数据,这个具体如何调用,详细大家结合之前学过的知识应该有所了解。
首先在user.js的data里初始化一个userInfo对象,用来接收数据:
data: { userInfo:{}
},
然后在事件处理函数getUserInfomation获取到的userInfo通过this.setData赋值给它,也就是getUserInfomation的函数为
function (event)
这时data里的userInfo就有用户信息了,我们可以在user.wxml添加以下代码来将数据渲染出来。
<view>{{userInfo.nickName}}</view> <view>{{userInfo.country}}</view> <image mode="widthFix" style="width:64px;height:64px" src="{{userInfo.avatarUrl}}"></image>
当我们再次点击“点击获取用户信息”的button按钮后,数据就渲染出来了。
这种方式只能在user页面才能获取到用户信息,限制非常大,那我们应该怎么做呢?我们要把获取到的用户信息写到app.js成为页面的公共信息,以后可以跨页面只需在user页面点击一次按钮即可。
在getUserInfomation将获取到的用户信息传给globalData的userInfo属性:
function (event)
关于用户登录以及信息获取,这里我们只是梳理了一些比较核心的知识点,还有一些大家可以去参考**模板小程序(也就是不使用云开发服务新建的这个小程序)**里的代码,这里有一套相对比较完整的案例。更具有实际开发意义的用户登录,之后会在云开发部分介绍。
发表评论: