本文已参与[新人创作礼]活动,一起开启掘金创作之路
登录注册页面
src\views\login\index.vue
1.设置redirect立即监听路由重定向数据
2.注册登录点击事件handleLogin
(1)内部调用Vuex的login事件
(2)是否有重定向,有则跳转回登录前页面无则跳转主页面
<el-button @click.native.prevent="handleLogin">登录</el-button>
...
watch: {
$route: {
handler: function(route) {
this.redirect = route.query && route.query.redirect
},
immediate: true
}
},
methods: {
handleLogin() {
this.$refs.loginForm.validate(async (valid) => {
if (valid) {
await this.$store.dispatch('user/login',this.loginForm).then((res)=>{
this.$router.push({ path: this.redirect || '/' })
} )
// this.$router.push('/')
} else {
console.log('error submit!!')
return false
}
})
}
}
主页面
src\layout\components\Navbar.vue
1.注册登出事件logout
(1)调用Vuex的logout事件
(2)跳转至登录页面并记录登出前页面
<el-dropdown-item divided @click.native="logout">
<span style="display:block;">Log Out</span>
</el-dropdown-item>
...
methods: {
async logout() {
await this.$store.dispatch('user/logout')
this.$router.push(`/login?redirect=${this.$route.fullPath}`)
}
}
路由配置
src\router\index.js
1.设置登录页面路由
2.设置主页页面路由
(1)设置子页面路由
(2)设置默认路由
3.设置重置事件
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
/* Layout */
import Layout from '@/layout'
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: 'Dashboard', icon: 'dashboard' }
}]
},
]
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
接口配置
src\api\user.js
1.设置登录接口
2.根据toekn获取用户信息接口
3.获取用户基本信息接口
import request from "@/utils/request";
/**
* @description: 登录
*/
export function loginApi(data) {
return request({
url: "/api/sys/login",
method: "post",
data,
});
}
//获取用户信息
export function getInfo(token) {
return request({
url: "/api/sys/profile",
method: "post"
});
}
/**
* @description: 获取用户头像
* @param {*} id 用户id
* @return {*}
*/
export function getUserDetailById(id) {
return request({
url: `/api/sys/user/${id}`
})
}
token工具
src\utils\auth.js
import Cookies from 'js-cookie'
const TokenKey = 'vue_admin_template_token'
export function getToken() {
return Cookies.get(TokenKey)
}
export function setToken(token) {
return Cookies.set(TokenKey, token)
}
export function removeToken() {
return Cookies.remove(TokenKey)
}
Vuex
src\store\modules\user.js
1.获取方法
2.设置state调用getDefaultState方法,设置Object.assign浅拷贝getDefaultState()返回值的信息
3.设置mutations对象存放用于存储state信息的方法
4.设置actions用于异步登录login,调用api中登录接口获取token并存储到state,注意这里的return new Promise()以及使用resolve()接收可以使用await替代
5.设置actions用于获取用户信息getInfo,调用获取用户信息,并将信息存储到state
6.设置actions用于登出logout,调用移除token,重置路由,调用Object.assign浅拷贝getDefaultState()返回值的信息
7.设置actions用于重置token的resetToken事件,重置token,调用Object.assign浅拷贝getDefaultState()返回值的信息
import { loginApi, getInfo,getUserDetailById } from "@/api/user";
import { getToken, setToken, removeToken } from "@/utils/auth";
import { resetRouter } from "@/router";
const getDefaultState = () => {
return {
token: getToken(),
name: "",
avatar: "",
userInfo: {},
};
};
const state = getDefaultState();
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState());
},
SET_TOKEN: (state, token) => {
state.token = token;
},
SET_NAME: (state, name) => {
state.name = name;
// console.log(state.name,'name');
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar;
},
SET_USERINFO: (state, userInfo) => {
state.userInfo = userInfo;
},
};
const actions = {
login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
loginApi(userInfo)
.then((response) => {
// console.log(response, 88888);
// getInfo();
const { data } = response;
// console.log(data,'data');
//将token存储到vuex的state中
commit("SET_TOKEN", data);
// token持久化====cookie来存储的
setToken(data);
resolve();
})
.catch((error) => {
reject(error);
});
});
},
// get user info
getInfo({ commit, state }) {
return new Promise(async(resolve, reject) => {
// getInfo((response)=>{
const response = await getInfo()
// console.log(response,'response');
commit("SET_USERINFO", response.data);
commit("SET_NAME",response.data.username);
// console.log(response.data.username,'name');
// })
});
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
removeToken(); // must remove token first
resetRouter();
commit("RESET_STATE");
resolve();
});
},
// remove token
resetToken({ commit }) {
return new Promise((resolve) => {
removeToken(); // must remove token first
commit("RESET_STATE");
resolve();
});
},
};
export default {
namespaced: true,
state,
mutations,
actions,
};
src\store\getters.js
设置getters将相应state的不同文件的变量赋予给state的自定义值,并将getters暴露
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name
}
export default getters
请求拦截器
src\utils\request.js
1.设置请求拦截器
(1)调用getToken事件获取token并将其添加到网址
import axios from "axios";
import { Message } from "element-ui";
import { getToken } from "@/utils/auth";
// create an axios instance
const service = axios.create({
timeout: 5000, // request timeout
});
// request interceptor
service.interceptors.request.use(
(config) => {
if (getToken()) {
// 携带请求头token
config.headers["Authorization"] = "Bearer " + getToken();
}
return config;
},
(error) => {
console.log(error); // for debug
return Promise.reject(error);
}
);
// response interceptor 响应拦截器
service.interceptors.response.use(
);
export default service;
路由导航守卫
src\permission.js
1.下载进度条包引入并设置
2.设置白名单
3.设置路由前置守卫(到哪去,从哪来,放行)
(1)开启进度条
(2)设置字体
(3)获取token
(4)根据token判断是否登录
/1 有token
//1 去的登录页面
///1 放行,关闭进度条
//2 去的不是首页
///1 已经获取到用户信息
////1 放行,关闭进度条
///2 未获取用户信息
////1 获取用户信息
////2 放行,关闭进度条
/2 没有token
//1 在白名单中
///1 放行,关闭进度条
//2 没在白名单中
///1 记录放行前页面
///2 放行并关闭进度条
import router from "./router";
import store from "./store";
import { Message } from "element-ui";
import NProgress from "nprogress"; // progress bar
import "nprogress/nprogress.css"; // progress bar style
import { getToken } from "@/utils/auth"; // get token from cookie
import getPageTitle from "@/utils/get-page-title";
NProgress.configure({ showSpinner: false }); // NProgress Configuration
const whiteList = ["/login"]; // no redirect whitelist
/* 路由导航守卫=====只要有路由值发生改变就会触发
beforeEach====跳转之前
afterEach=====跳转之后
*/
router.beforeEach(async (to, from, next) => {
NProgress.start();
document.title = getPageTitle(to.meta.title);
const hasToken = getToken();
// next();
// console.log(hasToken,'tt');
if (hasToken) {
//next();
if (to.path === "/login") {
next("/");
NProgress.done();
} else {
const hasGetUserInfo = store.getters.name; // 获取的用户信息
// console.log(hasGetUserInfo, 988);
if (hasGetUserInfo) {
next();
} else {
store.dispatch("user/getInfo");
next();
}
NProgress.done();
}
} else {
// // 表示没有登录
if (whiteList.includes(to.path)) {
next();
NProgress.done();
} else {
the login page.
next(`/login?redirect=${this.$route.fullPath}`);
NProgress.done();
}
}
});
router.afterEach(() => {
});
设置
vue.config.js
配置代理服务器解决跨域问题
module.exports = {
...
devServer: {
...
proxy:{
/* 代理服务器
+ 代理服务器:http://localhost:9999/
+ 目标服务器:http://ihrm-java.itheima.net
/api===只要请求地址中有api的就会进入代理服务器
'/api':{
target:'http://ihrm-java.itheima.net'
}
}
},