目的
上一节我们完成了登录,希望实现的效果是,登录成功后跳转到首页,此时右上角的登录按钮应该换成用户的头像。 要显示用户的头像,就意味着要拿到用户的数据,问题是,拿到之后要存储在哪里? 这里我们选择存储到vuex中,这样即使跨组价也能共享数据。
项目地址:https://github.com/cctyl/sunofbeach_mobile.git
实现
我们先把数据拿到。
在什么地方拿数据比较合适,我们选择在登录成功后获取用户数据,然后存储到vuex中。
api如下
这个接口有点问题。获取用户信息要传递id,那怎么知道自己的id呢?我找遍了整个文档,也没找到怎么获取自己的id,登录接口也没有返回自己的id。
坏了,卡在这里了。
然后就到页面上 f12,看sob主站是怎么拿到数据的。发现,它是通过 checkToken接口,返回的用户信息
这才是我们需要的api。地址如下:
https://api.sunofbeach.net/uc/user/checkToken
需要携带cookie请求(chrome可能会拦截掉,用firefox测试)
响应格式如下:
{
"success": true,
"code": 10000,
"message": "操作成功",
"data": {
"id": "1314408005793603584",
"roles": null,
"lev": 0,
"isVip": "0",
"avatar": "https://images.sunofbeaches.com/content/2021_10_09/896340281694093312.png",
"nickname": "ccTyL",
"fansCount": null,
"followCount": null
}
}
接下来就是,到api中写好接口方法,登录成功后调用方法拿到数据,存储到vuex中。
存储到vuex,首先要去state中声明这个变量 userInfo,然后 action中编写方法调用mutation,再到mutation中编写方法操作state
state.js
/*
存放各种需要共用的属性
*/
export default {
lastUrl:'',//记录上一次请求的url,用于登录后返回
userInfo:'',//用户信息
}
action.js
这里注意,我们不再是单纯的获取数据调用mutation
我们在这里发送请求
/*
通过操作mutations来操作state
*/
import api from '../api/index'
export default {
/**
* 设置最后一次的url
* @param context
* @param value
*/
setLastUrl(context, value) {
//commit
context.commit('SET_LAST_URL', value)
},
/**
* 存储用户信息
* @param context
* @param value
*/
async setUserInfo(context) {
//先调用接口查询数据
let checkTokenResult = await api.checkToken()
let userInfo = checkTokenResult.data
//commit
context.commit('SET_USER_INFO', userInfo)
},
}
mutation.js
/*
直接操作state的地方
*/
export default {
SET_LAST_URL(state,value){
//修改state
state.lastUrl=value
},
SET_USER_INFO(state,value){
//修改state
state.userInfo=value
},
}
写好之后,到login.vue,登录成功之后调用actions方法
//获取用户信息并存储到vuex
this.$store.dispatch('setUserInfo')
到浏览器登录后查看
这里查看我们使用的是vue的dev tool 插件,chrome和firefox都可以去应用商店下载,自行百度
cookie过期
这个cookie是有一个时间限制的,超时了就拿不到数据,所以对action中的方法进行改造
改造后,调用此方法,需要传递vue component对象,用来弹出提示框
/**
* 存储用户信息
* @param context
* @param vc vue组件对象,用来弹出提示框
*/
async setUserInfo(context,vc) {
//先调用接口查询数据
let checkTokenResult = await api.checkToken()
//判断cookie是否超时了
// {"success":false,"code":11126,"message":"账号未登录","data":null}
if (!checkTokenResult.success) {
//提示
vc.$notify.warn("登录信息已过期,请重新登录")
//超时了就清空原本的数据
context.commit('SET_USER_INFO', null)
} else {
//没超时,正常存储
let userInfo = checkTokenResult.data
//commit
context.commit('SET_USER_INFO', userInfo)
}
},
调用时:
//获取用户信息并存储到vuex
this.$store.dispatch('setUserInfo',this) //this就是vc组件对象
持久化
vuex的数据,在刷新页面之后就会消失,这样可不行,所以每次刷新都重新请求一下,
这个部分,我们到App.vue中去实现
mounted() {
//检查token时效并获取用户信息
this.$store.dispatch('setUserInfo',this)
},
然后去刷新页面,每次刷新后vuex中都有userInfo,说明成功了