登录功能
1.阅读接口文档,封装登录接口
2.登录前的校验(手机号,图形验证码,短信验证码)
3.调用方法,发送请求,成功添加提示并跳转
封装登录接口
js
// 登录
export const codeLogin = (mobile, smsCode) => {
return request.post('/passport/login', {
form: {
isParty: false, // 是否第三方登录
partyData: {}, // 第三方登录信息
mobile, // 手机号
smsCode // 短信验证码
}
})
}
登录逻辑
js
async login() {
// 校验
if (!this.vaildFn()) return
if (!this.timer) {
this.$toast('请先获取短信验证码')
return
}
if (!this.msgCode) {
this.$toast('请输入短信验证码')
return
}
if (!/^\d{6}/.test(this.msgCode)) {
this.$toast('短信验证码格式不正确')
return
}
const res = await codeLogin(this.mobile, this.msgCode)
this.$store.commit('user/setUserInfo', res.data)
// 登录成功后清理倒计时
this.clearCountdown()
// 登录
this.$toast('恭喜登录成功')
this.$router.push('/')
}
响应拦截器统一处理错误
js
import axios from 'axios'
import { Toast } from 'vant'
const instance = axios.create({
baseURL: 'https://smart-shop.itheima.net/index.php?s=/api/',
timeout: 5000
})
axios.interceptors.request.use(
function (config) {
return config
},
function (error) {
return Promise.reject(error)
}
)
instance.interceptors.response.use(
function (response) {
const res = response.data
if (res.status !== 200) {
Toast(res.message)
return Promise.reject(res.message)
}
return res
},
function (error) {
return Promise.reject(error)
}
)
export default instance
登录权证信息存储
js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
getters: {},
mutations: {},
actions: {},
modules: {
user
}
})
src\store\modules\user.js
js
export default {
namespaced: true,
state() {
return {
// 个人权证相关
userInfo: {
token: '',
userId: ''
}
}
},
mutations: {},
actions: {},
getters: {}
}
js
async login() {
// 校验
if (!this.vaildFn()) return
if (!this.timer) {
this.$toast('请先获取短信验证码')
return
}
if (!this.msgCode) {
this.$toast('请输入短信验证码')
return
}
if (!/^\d{6}/.test(this.msgCode)) {
this.$toast('短信验证码格式不正确')
return
}
const res = await codeLogin(this.mobile, this.msgCode)
this.$store.commit('user/setUserInfo', res.data)
// 登录成功后清理倒计时
this.clearCountdown()
// 登录
this.$toast('恭喜登录成功')
this.$router.push('/')
}
storage存储模块-vuex持久化处理
js
const INFO_KEY = 'hm_shopping_info'
export const getInfo = () => {
const defaultObj = {
token: '',
userId: ''
}
const result = window.localStorage.getItem(INFO_KEY)
return result ? JSON.parse(result) : defaultObj
}
export const setInfo = (obj) => {
window.localStorage.setItem(INFO_KEY, JSON.stringify(obj))
}
export const removeInfo = () => {
window.localStorage.removeItem(INFO_KEY)
}
添加请求loading效果
js
import axios from 'axios'
import { Toast } from 'vant'
const instance = axios.create({
baseURL: 'https://smart-shop.itheima.net/index.php?s=/api/',
timeout: 5000
})
instance.interceptors.request.use(
function (config) {
Toast.loading({
forbidClick: true, // 禁止背景点击
message: '加载中...',
loadingType: 'spinner', // 加载图标
duration: 0 // 不会自动消息
})
return config
},
function (error) {
return Promise.reject(error)
}
)
instance.interceptors.response.use(
function (response) {
const res = response.data
if (res.status !== 200) {
Toast(res.message)
return Promise.reject(res.message)
}
Toast.clear()
return res
},
function (error) {
return Promise.reject(error)
}
)
export default instance
页面访问拦截
js
const authUrls = ['/pay', '/myorder']
// 全局前置导航守卫
router.beforeEach((to, from, next) => {
// 非权限页面
if (!authUrls.includes(to.path)) {
next()
return
}
// 需要权限的页面
const token = store.getters.token
if (!token) {
next('/login')
return
}
next()
})
js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
Vue.use(Vuex)
export default new Vuex.Store({
state: {},
getters: {
token(state) {
return state.user.userInfo.token
}
},
mutations: {},
actions: {},
modules: {
user
}
})