一、网络请求和相应拦截器
// 此vm参数为页面的实例,可以通过它引用vuex中的变量
module.exports = (vm) => {
// 初始化请求配置
uni.$u.http.setConfig((config) => {
config.baseURL = 'http://127.0.0.1:8080/';
return config
})
// 请求拦截
uni.$u.http.interceptors.request.use((config) => {
//根据custom参数中配置的是否需要token,添加对应的请求头
if(config?.custom?.auth) {
config.header.token = uni.getStorageSync("token")
}
return config
}, config => { // 可使用async await 做异步操作
return Promise.reject(config)
})
uni.$u.http.interceptors.response.use((response) => {
/* 对响应成功做点什么 可使用async await 做异步操作*/
if (response.data.code !== 200) { // 服务端返回的状态码不等于200,则reject()
return Promise.reject(response)
} // return Promise.reject 可使promise状态进入catch
if (response.config.custom.verification) { // 演示自定义参数的作用
return response.data
}
return response
}, (response) => {
/* 对响应错误做点什么 (statusCode !== 200)*/
console.log(response)
return Promise.reject(response)
})
}
二、main.js文件引入拦截器
注意:
将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用
// 引入请求封装,将app参数传递到配置中
require('./common/http.interceptor.js')(app)
三、创建API集中管理文件
const http = uni.$u.http
// 登录接口(获取code) post请求
export const getLoginCode = (data) => http.post('wx/code/' + data)
//登录接口(用户登录) post请求
export const realyLoginInfo = (params, config = {}) => http.post('wx/login', params,config)
四、登录页面引用API并使用
import {getLoginCode,realyLoginInfo} from '@/common/http.api.js'
五、登录页完整代码示例
<template>
<view>
<view>
<view style="margin-top: 100rpx;background-color: aquamarine;">
</view>
<!-- 获取头像 -->
<view style="margin-top: 50rpx;">
<button class="avatar-button" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :class="avatarUrl ==''?'avatar-img':'' " :src="avatarUrl"></image>
</button>
</view>
<!-- 输入用户名 -->
<view class="nickname-code">
<view class="nickname-title">昵称:</view>
<input style="text-align: center;width: 80%;" type="nickname" @blur="getNickName" placeholder="请输入微信昵称"/>
</view>
<view class="login-btn">
<button class="btn-normal" style="background: #4059f8;" :disabled="avatarUrl == ''? true:false" @click="doLogin()">授权登录</button>
</view>
</view>
<view>
<!-- 登录弹框 -->
<u-popup :round="20" :show="phoneModalShow" mode="center" border-radius="14" >
<view class="sq_box">
<view>授权登录</view>
<view>授权获取您的手机号</view>
<view>
<view class="agreement_warp">
<view>登录代表您已同意</view>
<view @click="agreenmentDetailHandle" style="color: #ff431e;">隐私政策</view>
</view>
<u-button style="width: 100%;" type="success"
@getphonenumber="getphonenumber" open-type="getPhoneNumber">
微信快捷授权登录
</u-button>
</view>
</view>
</u-popup>
</view>
</view>
</template>
<script>
import {getLoginCode,realyLoginInfo} from '@/common/http.api.js'
export default {
data() {
return {
userRawData:{},
LoginCodeMsg:{},
// 手机号隐藏层
phoneModalShow: false,
// 头像
avatarUrl: '',
// 用户名
nickname: '',
// 登录 code
logCode: "",
isLogin: false,
userInfo:{}
}
},
onLoad() {
},
methods: {
// 跳转到 隐私政策页面
agreenmentDetailHandle() {
uni.navigateTo({
url: '/pages/mine/agreement'
})
},
//获取用户昵称
getNickName(e){
console.log(e.target.value)
this.nickname = e.target.value
this.userInfo.nickName = this.nickname
},
//调用微信登录
doLogin(){
uni.login({
provider:'weixin',
success: (logRes) => {
console.log(logRes.code)
this.logCode = logRes.code
getLoginCode(logRes.code).then(res => {
if(res.data.code == 200){
this.userInfo.openId = res.data.openId
this.LoginCodeMsg.openId = res.data.openId
this.LoginCodeMsg.sessionKey = res.data.sessionKey
this.phoneModalShow = true;
}else{
uni.showToast({
title: '微信登录失败',
icon: 'none'
})
}
})
},
})
},
//获取用户头像
onChooseAvatar(e) {
this.avatarUrl = e.detail.avatarUrl
console.log(e.detail.avatarUrl)
this.userInfo.avatarUrl = e.detail.avatarUrl
},
//获取手机号
getphonenumber(e){
let phoneMsg = {
encryptedData: e.detail.encryptedData,
iv: e.detail.iv,
openId: this.LoginCodeMsg.openId,
sessionKey: this.LoginCodeMsg.sessionKey,
avatar: this.userRawData.avatarUrl,
nickName: this.userRawData.nickname,
sex: ''
}
realyLoginInfo(phoneMsg).then(res =>{
this.phoneModalShow = false
if(res.data.code == 200){
this.isLogin = true
uni.showToast({
title:'登录成功',
icon:'none'
})
this.userInfo.level = res.data.busInfo.userType
//缓存登录状态和用户信息
this.userInfo.token = res.data.token
uni.setStorageSync('isLogin','true')
// this.$store.state.busInfo = res.data.busInfo;
// this.$store.state.hasLogin = this.isLogin;
// this.$store.state.userInfo = this.userInfo;
// this.$store.state.token = res.data.token;
uni.setStorageSync('isLogin','true')
//将当前代理的个人信息存入缓存中
uni.setStorageSync('busInfo',res.data.busInfo)
setTimeout(function (){
uni.navigateBack()
},2000)
}else{
uni.showToast({
title:'登录失败',
icon:'error',
duration:2000
})
}
})
},
}
}
</script>
<style>
page {
background-color: #fff;
}
</style>
<style lang="scss" scoped>
// 用户头像
.avatar-button {
width: 120rpx;
padding: 0;
border-radius: 50%;
margin: 30rpx auto 0 auto;
image {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
display: block;
border: 4rpx solid #d8bf9f;
}
}
.avatar-img {
z-index: 3;
position: relative;
&:before {
content: '请选择头像';
position: absolute;
top: 0;
left: 0;
width: 120rpx;
height: 120rpx;
// line-height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
color: #ffffff;
font-size: 25rpx;
background-color: rgba(130, 128, 127, 0.5);
z-index: 4;
}
}
//用户昵称
.nickname-code {
display: flex;
align-items: center;
padding: 60rpx 20rpx 20rpx 20rpx;
margin-top: 40rpx;
background-color: #ffffff;
border-radius: 20rpx 20rpx 20rpx 20rpx;
// border-radius: 50rpx 50rpx 0 0;
.nickname-title {
// font-size: 50rpx;
// color: #9e794b;
margin-right: 15rpx;
}
.weui-input {
flex: 1;
color: #9e794b;
font-size: 40rpx;
}
}
.login-btn {
padding: 0 20rpx;
}
.login-btn button {
background: #23ac3a;
border-radius: 999rpx;
color: rgb(255, 255, 255);
font-size: 30rpx;
height: 88rpx;
line-height: 88rpx;
text-align: center;
margin-top: 60rpx
}
.sq_box {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
margin: 5% 0;
width: 700rpx;
// height: 300rpx;
}
.sq_name {
margin: 40rpx;
font-weight: bold;
font-size: 32rpx;
}
.sq_msg {
font-size: 30rpx;
color: #606266;
text-align: left;
}
.fontsize {
font-size: 34rpx;
}
.btn_warp {
position: absolute;
bottom: 20rpx;
left: 0;
width: 100%;
height: 150rpx;
/* background-color: #7DCC7C; */
}
.agreement_warp {
display: flex;
justify-content: center;
align-items: center;
color: #999999;
margin: 20rpx 0;
}
</style>