04-vuePC端项目(layout页面布局,权限控制的路由导航守卫,嵌套路由,axios发送请求前拦截器,响应数据前拦截器)
登录成功之后完成layout页面layout文件夹下的index.vue<template><el-container class="layout"><el-header class="header"><div class="left"><i class="el-icon-s-fold" @click="isCollapse=!isCollap
登录成功之后完成layout页面
layout文件夹下的index.vue
<template>
<el-container class="layout">
<el-header class="header">
<div class="left">
<i class="el-icon-s-fold" @click="isCollapse=!isCollapse"></i>
<img src="@/assets/layout_icon.png" class="marginlr" alt />
<span class="title">黑马面面</span>
</div>
<div class="right">
<img :src="avatar" alt />
<span class="name">{{username}},您好</span>
<el-button size="mini" type="primary" @click="logout">退出</el-button>
</div>
</el-header>
<el-container>
<el-aside width="auto">
<!-- 左侧导航栏 -->
<el-menu default-active="5" class="el-menu-vertical-demo" :collapse="isCollapse" router>
<el-menu-item index="/layout/chart">
<i class="el-icon-pie-chart"></i>
<span slot="title">数据概览</span>
</el-menu-item>
<el-menu-item index="/layout/user">
<i class="el-icon-user"></i>
<span slot="title">用户列表</span>
</el-menu-item>
<el-menu-item index="/layout/question">
<i class="el-icon-edit-outline"></i>
<span slot="title">题库列表</span>
</el-menu-item>
<el-menu-item index="/layout/enterprise">
<i class="el-icon-office-building"></i>
<span slot="title">企业列表</span>
</el-menu-item>
<el-menu-item index="/layout/subject">
<i class="el-icon-notebook-2"></i>
<span slot="title">学科列表</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-main style="background-color: #e8e9ec">
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
// 按需导入
import { removeToken } from "@/ultils/token";
export default {
data() {
return {
isCollapse: false, //导航栏是否展示
avatar: "", //用户头像
username: "" //用户昵称
};
},
methods: {
// 发送请求得到用户信息
async getUserData() {
const res = await this.$axios.get("/info", {
//这个在发送axios里面带过去也可以,但是后面每个请求都要写并且post与get方法写的地方还不一样
// 就很麻烦,可以写在拦截器里面,只要发送请求都会先经过那里
// headers: {
// token: getToken(),//在请求头把token带过去
// }
});
// console.log(res);
if (res.data.code == 200) {
this.avatar = process.env.VUE_APP_BASEURL + "/" + res.data.data.avatar;
this.username = res.data.data.username;
}
},
// 退出
logout() {
this.$confirm("确定退出吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(async () => {
const res = await this.$axios.get("/logout");
if (res.data.code == 200) {
//退出要把token删掉
removeToken();
//还要去到登录页面
this.$router.push("/login");
}
})
.catch(() => {});
}
},
created() {
this.getUserData();
}
};
</script>
项目说明:
01-权限控制
前端要做
- 导航守卫:简单一点说就是当你没有登录的时候(也就没有token),就看你有没有登录,没登录就没权限访问其他路由的页面,就都要被打回登录页面去
直通车:直通车: vue Router中文档中的导航守卫.- 作用:我们没进入一个页面之前,它会拦截到,然后,在导航守卫中进行判断,如果有权限,就让你访问你要去的页面,如果没有权限,可以通过路由跳转到指定页面
- 是一个函数,它里面有三个参数:
to, 我们要去的页面
from,之前的页面
next,控制着你是否有权,访问你想去的页面
- 代码实现
在 src/router/index.js 中写导航守卫的代码:
// 按需导入(要用到这个所以要导入)
import { getToken} from '@/ultils/token'
// 全局导航守卫
router.beforeEach((to, from, next) => {
//console.log(to);
// console.log(from);
//先判断to的是不是登录页面,如果是登录页面就没必要守卫直接通关
if (to.fullPath == "/login") {
next()
} else {
// 如果to的不是非登录页面,那就判断你有没有先登录能不能取到token,如果能就表示你登录了让你通关,没有登录就打回登录页面
const token = getToken()
if (token) {
next(); //去到你想去的地方
} else {
next("/login")
}
}
})
后台也要做
比如有些是从postman里面添加数据啥的也不行所以后台也要控制把关做权限控制
02-layout页面布局
容器布局
直通车: elementui里面的Container布局容器.
菜单
1、直通车: elementui里面的NavMenu导航菜单.
2、 其它:
- 控制菜单的展开和收起:collapse=“isCollapse” ,由这个isCollapse是true还是false决定,默认false是展开的
- 控制高亮
el-menu-item 上面的 index
el-menu中的default-active
点击左边菜单项,希望发生的变化
1、浏览器的导航栏中,路由地址发生改变
el-menu,设置 router 属性为true
更改 el-menu-item 中的 index的值,改成路径
2、右边内容部分也要发生变化: 嵌套路由
3、左边的高亮状态发生改变,并且刷新也能够显示正常
03-嵌套路由
在 router.js 中配置
直通车: vue Router文档中的嵌套路由.
应用场景:
后台管理系统中
步骤:
1、在layout.vue中的 右边设置一个 router-view
2、在 src/router/index.js 中配置 layout页面右边的路由规则
嵌套路由:注意嵌套着的路由的path:‘chart’ 这种千万别在chart前面加/,否则出有问题
const router = new VueRouter({
routes: [
{
path: '/login',
component: Login
},
{
path: '/layout',
component: Layout,
//这个children数组里面的就是嵌套着的路由
children: [
{path:'chart',component:Chart},
{path:'user',component:User},
{path:'enterprise',component:Enterprise},
{path:'question',component:Question},
{path:'subject',component:Subject},
]
},
{
path: '/',
redirect: '/login'
}
]
});
] },
3、还要在layout结构中的对应的嵌套结构中里面写上router-view标签
<el-main style="background-color: #e8e9ec">
<router-view></router-view>
</el-main>
04个人信息展示与退出
- 个人信息获取:
发送请求得到个人信息,它需要请求头中携带token(因为要保证你确定是登录了的,如果是登录了的就一定可以拿到token才能发送请求响应回来给你)
1、在每个请求中都写设置请求头的代码: 每一都得写,并且get方法和post方法写的地方还不一样,这个被注释掉的就很麻烦
created() {
this.getUserData();
},
methods: {
// 发送请求得到用户信息
async getUserData() {
const res = await this.$axios.get("/info", {
//这个在发送axios里面带过去也可以,但是后面每个请求都要写并且post与get方法写的地方还不一样
// 就很麻烦,可以写在拦截器里面,只要发送请求都会先经过那里
// headers: {
// token: getToken(),//在请求头把token带过去
// }
});
// console.log(res);
if (res.data.code == 200) {
this.avatar = process.env.VUE_APP_BASEURL + "/" + res.data.data.avatar;
this.username = res.data.data.username;
}
},
比如在get请求中携带token
比如在post请求中携带token
2、我们可以统一的在请求拦截器中设置请求头(src/utils/request.js中编写),好处就是只用写一次。
直通车: axios中的拦截器Interceptors.
src/ultils/request.js文件下:
// 按需导入
import { getToken } from "@/ultils/token";
import { removeToken } from "@/ultils/token";
import router from '@/router/index'
// 请求拦截器,发送请求前要经过这里,发送请求要把token带过去可以在这里面写
axios.interceptors.request.use(function (config) {
// Do something before request is sent
const token = getToken()
if (token) {
config.headers.token = token
}
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
//响应拦截器,返回的数据都要先经过这里,可以把token过期的处理可以在这里写
axios.interceptors.response.use(function (response) {
// Do something with response data
// 如果响应回来的code为206说明就是token过期了,那就要返回登录页面并且把token删除
if (response.data.code == 206) {
removeToken();
// 这个js里面可以把router文件夹下的index.js实例化的router拿过来就相等于vue的单文件组件的this.$router
router.push('/login')
return;
}
//如果没问题就返回响应
return response;
}, function (error) {
// Do something with response error
return Promise.reject(error);
});
- 退出
直通车: elementui中的MessageBox 弹框.
弹出一个框问客户确定退出吗?用户选择确定之后,我们需要做如下的事情
1、发请求,告诉后台该用户要退出了,后台应该要做一些处理
2、退出成功之后,做两件事情,第一 删除token,第二 跳转到登录页面
更多推荐
所有评论(0)