router
export const constantRouterMap = [ { path: '/login', component: () => import('@/views/login/index'), hidden: true }, ... ] #在路由js中,加入/login路由,hidden为true
views
<template> <div class="login-container"> <el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form" auto-complete="on" label-position="left"> <h3 class="title">运维没烦恼</h3> <el-form-item prop="username"> <el-input v-model="loginForm.username" name="username" type="text" auto-complete="on" placeholder="username" /> </el-form-item> <el-form-item prop="password"> <el-input v-model="loginForm.password" name="password" auto-complete="on" placeholder="password" @keyup.enter.native="handleLogin" /> </el-form-item> </el-form> </div> </template> #先做一个form,带表单验证功能,将用户输入的账户信息给到loginForm
handleLogin() { this.$refs.loginForm.validate(valid => { if (valid) { this.loading = true this.$store.dispatch('Login', this.loginForm).then(() => { this.loading = false this.$router.push({ path: this.redirect || '/' }) }).catch(() => { this.loading = false }) } else { console.log('error submit!!') return false } }) } #把loginForm使用vuex传递到Login
auth
Login({ commit }, userInfo) { const username = userInfo.username.trim() return new Promise((resolve, reject) => { login(username, userInfo.password).then(response => { setToken(response.token) commit('SET_TOKEN', response.token) resolve() }).catch(error => { reject(error) }) }) }, #将账户信息传入login api,成功的话,后端api返回一个{‘token’:'value'}的字典
export function setToken(token) { return Cookies.set(TokenKey, token) } #把token写入cookie
NProgress
export function getToken() { return Cookies.get(TokenKey) } #从cookie获取token的函数
const whiteList = ['/login'] // 不重定向白名单 router.beforeEach((to, from, next) => { NProgress.start() if (getToken()) { if (to.path === '/login') { next({ path: '/' }) NProgress.done() // if current page is dashboard will not trigger afterEach hook, so manually handle it } else { // next() if (store.getters.roles.length === 0) { store.dispatch('GetInfo').then(res => { // 拉取用户信息 next() }).catch((err) => { store.dispatch('FedLogOut').then(() => { Message.error(err || 'Verification failed, please login again') next({ path: '/' }) }) }) } else { next() } } } else { if (whiteList.indexOf(to.path) !== -1) { next() } else { next(`/login?redirect=${to.path}`) // 否则全部重定向到登录页 NProgress.done() } } }) #检测url定向,如果使用getToken能从cookie获取到token,则说明用户已登录 #如果to页面为/login、则next到/ #如果不是to /login,如果store中roles的长度为0,则调用GetInfo函数 #再next
GetInfo({ commit, state }) { return new Promise((resolve, reject) => { getInfo(state.token).then(response => { const data = response.data if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组 commit('SET_ROLES', data.roles) } else { reject('getInfo: roles must be a non-null array !') } commit('SET_NAME', data.name) commit('SET_AVATAR', data.avatar) resolve(response) }).catch(error => { reject(error) }) }) }, #调用getInfo api,传入token,返回的response.data包含三个key,roles,name,avaoar。写入state。