前言
uni-app 实现微信小程序、头条小程序、手机号登陆
一、login.vue
<template>
<view class="container">
<view class="pageTitle">
<image src="/static/logo.png"></image>
</view>
<view>
<view v-if="loginType === 'phone'" class="input-content">
<view class="input-item">
<input type="number" :value="phone" placeholder="请输入手机号码" placeholder-style="color:#E5E5E5" maxlength="11" data-key="phone"
@input="inputChange">
</view>
<view class="input-item">
<view class="verify-code">
<view>
<input type="mobile" :value="vcode" placeholder="请输入验证码" maxlength="6" data-key="vcode"
style="" @input="inputChange" placeholder-style="color:#E5E5E5">
</view>
<view style="border-left: 1px solid #D8D8D8;">
<button class="verify-btn" :disabled="sendDisabled" @click="doGetVerify" :loading="sendLoading">
{{ sendText }}
</button>
</view>
</view>
</view>
</view>
<!-- #ifdef MP-WEIXIN -->
<button v-if="loginType !== 'phone'" class="confirm-btn" :disabled="logining" @click="miniWechatLogin">
微信授权登录
</button>
<!-- #endif -->
<!-- #ifdef MP-TOUTIAO -->
<button v-if="loginType !== 'phone'" class="confirm-btn" :disabled="logining" @click="touTiaoLogin">
头条授权登录
</button>
<!-- #endif -->
<button v-if="!loginType" class="confirm-btn mobile-btn" :disabled="logining" @click="chooseLoginType('phone')">
手机号登录
</button>
<button v-if="loginType === 'phone'" class="confirm-btn" :disabled="logining" @click="toPhoneLogin">
登录
</button>
</view>
</view>
</template>
<script>
import {
mapMutations
} from 'vuex'
export default {
data() {
return {
loginType: '',
phone: '',
vcode: '',
password: '',
logining: false,
sendText: '获取验证码',
sendDisabled: false,
sendLoading: false,
}
},
onShow() {
},
onLoad(options) {
},
methods: {
...mapMutations(['login']),
onBackPress(options) {
const that = this
if(options.from === 'backbutton' && that.loginType !== ''){
this.loginType = ''
uni.setNavigationBarTitle({
title: '登陆'
});
return true
}
return false
},
inputChange(e) {
const key = e.currentTarget.dataset.key
this[key] = e.detail.value
},
chooseLoginType(type) {
this.loginType = type
if(type === 'phone'){
uni.setNavigationBarTitle({
title: '手机号登陆'
});
}
},
navBack() {
uni.navigateBack()
},
async toPhoneLogin() {
const that = this
if (that.phone.length !== 11) {
that.$api.msg('请输入11位中国手机号')
return
}
const timestamp = new Date().getTime()
const parameters = {
mobile: that.phone,
vcode: that.vcode,
timestamp
}
that.$api.request.httpGet('auth/request/token', parameters, res => {
that.logining = false
if (res) {
that.$api.msg(res.message)
}
}).then(res => {
that.logining = false
const tokenInfo = res.token;
const token = tokenInfo.token;
const userid = tokenInfo.userId;
that.getUserInfo(userid, token)
})
},
// #ifdef MP-WEIXIN
miniWechatLogin() {
const that = this
that.logining = true
const loginType = 1
uni.getUserProfile({
desc: '登录',
success: (loginRes) => {
uni.showLoading({
title: '登录中'
})
that.logining = true
uni.login({
provider: 'weixin',
success: wxres => {
that.logining = true
const raw = JSON.stringify(wxres)
const userInfo = loginRes.userInfo
const loginData = {}
loginData.nickName = userInfo.nickName
loginData.avatarUrl = userInfo.avatarUrl
loginData.gender = userInfo.gender
that.thirdBindOuth(wxres.code, loginRes.rawData, loginRes.signature, loginRes.encryptedData, loginRes.iv, 'weixin')
uni.hideLoading()
that.logining = false
},
fail: (res) => {
that.logining = false
uni.hideLoading();
that.$api.msg('登陆失败')
}
})
},
fail(res) {
that.logining = false
that.$api.msg('已取消登陆')
that.navBack()
}
})
},
// #endif
// #ifdef MP-TOUTIAO
touTiaoLogin() {
const that = this
that.logining = true
const loginType = 1
uni.login({
provider: 'toutiao',
success: wxres => {
}
})
uni.getUserProfile({
desc: '登录',
success: (loginRes) => {
uni.showLoading({
title: '登录中'
})
that.logining = true
uni.login({
provider: 'toutiao',
success: wxres => {
const userInfo = loginRes.rawData
const loginData = {}
loginData.nickName = userInfo.nickName
loginData.avatarUrl = userInfo.avatarUrl
loginData.gender = userInfo.gender
that.thirdBindOuth(wxres.code, loginRes.rawData, loginRes.signature, loginRes.encryptedData, loginRes.iv, 'toutiao')
uni.hideLoading()
that.logining = false
},
fail: (res) => {
that.logining = false
uni.hideLoading();
that.$api.msg('登陆失败')
}
})
},
fail(res) {
that.logining = false
that.$api.msg('已取消登陆')
that.navBack()
}
})
},
// #endif
doGetVerify() {
const that = this
if (!that.phone || that.phone.length !== 11) {
that.$api.msg('请输入正确手机号!')
return
}
const timestamp = new Date().getTime()
const parameters = {
mobile: that.phone,
timestamp
}
this.sendLoading = true
that.$api.request.httpGet('auth/request/verification/code', parameters, res => {
if (res) {
that.$api.msg(res.message)
}
this.sendLoading = false
}).then(res => {
that.$api.msg("验证码发送成功!")
that.sendDisabled = true
this.sendLoading = false
let sec = 60
const interval = setInterval(() => {
sec--
that.sendText = '重发 (' + sec + ')'
if (sec <= 0) {
that.sendDisabled = false
that.sendText = '获取验证码'
clearInterval(interval)
}
}, 1000)
})
},
thirdBindOuth(code, rawdata, minisignature, encrypteddata, iv, oauthtype) {
const that = this
const timestamp = new Date().getTime()
const parameters = {
code,
rawdata,
minisignature,
encrypteddata,
iv,
oauthtype,
timestamp
}
that.$api.request.httpPost('auth/bind/oauth', parameters, res => {
that.logining = false
if (res) {
that.$api.msg(res.message)
}
}).then(res => {
const tokenInfo = res.token;
const token = tokenInfo.token;
const userid = tokenInfo.userId;
if(tokenInfo && token && userid){
that.getUserInfo(userid, token)
} else {
that.$api.msg('登陆失败')
}
})
},
getUserInfo(userId, token) {
const that = this
const timestamp = new Date().getTime()
const parameters = {
userid: userId
timestamp: timestamp
}
that.$api.request.httpGet('user/get/info/', parameters, res => {
if (res) {
that.$api.msg(res.message)
}
}).then(res => {
const resUser = res.user
const userInfo = {}
userInfo.userId = userId
userInfo.token = token
userInfo.nickName = resUser.nickname
userInfo.avatarUrl = resUser.avatarUrl
userInfo.gender = resUser.gender
userInfo.userName = resUser.userName
userInfo.mobile = resUser.mobile
userInfo.name = resUser.name
userInfo.email = resUser.email
userInfo.company = resUser.company
userInfo.userType = resUser.userType
uni.setStorageSync('userInfo', userInfo)
that.$store.commit('login', userInfo)
that.$api.msg("登陆成功!")
setTimeout(() => {
const routeUrl = that.$api.prePage().route;
if (routeUrl) {
uni.navigateBack({ url: routeUrl})
} else {
uni.switchTab({
url: '../personal/index'
});
}
}, 1000)
})
},
}
}
</script>
<style lang="scss">
.container {
padding-top: 115px;
}
.pageTitle {
width: 100%;
text-align: center;
font-size: 25px;
image {
width: 120px;
height: 90px;
}
}
.confirm-btn {
width: 345px;
height: 45px;
margin: 20% auto 0;
background: $uni-color-primary;
color: #fff;
font-size: 18px;
font-weight: 500;
}
.input-content {
margin-top: 50px;
padding: 0 60rpx;
}
.verify-btn {
width: 100px;
height: 40px;
line-height: 40px;
background: #FFFFFF;
font-weight: 500;
font-size: 14px;
color: #2C2D2C;
//border: 1px solid #D8D8D8;
}
.mobile-btn {
/* #ifdef MP-WEIXIN || MP-TOUTIAO */
background: #FFFFFF;
border: 1px solid #D8D8D8;
box-sizing: border-box;
color: #5A5B5B;
margin-top: 30px;
/* #endif */
}
.input-item {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
padding: 0 0 0 $ap-page-padding;
margin-bottom: 50rpx;
box-sizing: border-box;
border: 1px solid #D8D8D8;
&:last-child {
margin-bottom: 0;
}
input {
height: 40px;
font-size: 16px;
font-weight: 500;
width: 100%;
line-height: 40px;
}
.verify-code {
flex-direction: row;
display: flex;
justify-content: space-between;
width: 100%;
uni-button:after{
border: none;
outline: none;
}
// &::after {
// border: none;
// outline: none;
// }
}
}
</style>