VUE项目实战17通过接口获取菜单并渲染
Posted 光仔December
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了VUE项目实战17通过接口获取菜单并渲染相关的知识,希望对你有一定的参考价值。
接上篇《16、主页Header和左侧菜单栏布局》
上一篇我们编写了头部Header和左侧菜单栏的布局样式,本篇我们来通过接口获取菜单数据,并重新加载菜单至左侧菜单栏。
一、获取菜单数据的权限
我们需要通过接口获取菜单数据,而菜单必须是在登录之后才能访问的,所以未登录前直接访问菜单接口是会被拒绝。那么登录之后又如何让接口认定前端已有权限获取数据了呢?我们回顾一下API文档中的注意事项:
即我们获取需要授权的API的数据时,必须将我们登录时获取的token令牌,封装到http请求头的Authorization字段中。
那么我们如何给每一个请求的Authorization字段添加token值呢?如果每个数据请求方法都自己加,显然十分繁琐和冗余。我们可以使用axios的请求拦截器添加token,即在每个http请求发出之前,进行再次封装,将token值封装进去之后,再进行请求。
下面是使用拦截器的样例代码:
//axios请求拦截
axios.interceptors.request.use(config => {
//为请求头对象,添加Token验证的Authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token');
return config;
})
我们可以调用axios的interceptors属性,该属性有一个request成员,这个request就是一个请求拦截器。它的use函数为请求拦截器挂载一个回调函数,在使用axios进行网络请求时,会优先调用use函数。
所以我们需要实现,请求在到达服务器之前,使用对http请求头进行一个预处理,将token封装到请求头的Authorization属性中。
如何实现?我们在main.js中设置(之前的默认请求路径和$Http对象的指定都是在这个文件):
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import './plugins/element.js'
//导入全局样式表
import './assets/css/global.css'
import axios from 'axios'
axios.defaults.baseURL = 'https://127.0.0.1:8888/api/private/v1/' //定义根路径
//为axios添加拦截器
axios.interceptors.request.use(config =>{
console.log(config);
return config;//最后必须返回config
})
Vue.prototype.$http = axios //在原型链上给$http赋值为axios对象
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount('#app')
我们先打印出来config,看看是个什么东西:
我们可以看到之前指定的beseURL在config对象中是有的,然后其中的headers,就是http请求的头对象,目前是有一个“Accept”属性,用来指定请求的文本类型等,我们可以为其添加一个Authorization属性。
修改use函数,为请求头封装token:
//为axios添加拦截器
axios.interceptors.request.use(config =>{
console.log(config);
config.headers.Authorization = window.sessionStorage.getItem('token');
return config;//最后必须返回config
})
然后我们来测试一下,Authorization中是否会封装进token。
首先点击Home页的退出或清除浏览器缓存,让系统处于未登录状态。在登录页面点击登录,此时我们F12查看网络请求,login的请求中,Authorization是空的,那是因为我们当前还未获取到token:
我们下面编写获取菜单的代码,在请求菜单的时候,我们看看Authorization是否有值。
二、获取菜单数据
首先我们来看一下左侧菜单栏的API文档:
我们请求的是“menu”服务,而这个服务返回的是一个大的data对象和一个meta对象,其中meta是我们请求的结果对象,status是200的话,代表我们请求成功。data是服务器返回的菜单列表,其中id是菜单的主键,authName是菜单的名称。path是菜单的链接路径,children是菜单的子菜单,如果没有就是一个空数组。
下面我们在Home.vue中编写加载菜单的代码。因为菜单是在页面开始加载的时候就需要渲染上去,所以我们需要在生命周期函数created方法中定义获取菜单的方法:
<script>
export default {
data(){
return {
//左侧菜单数据
menuList:[]
}
},
created(){
this.getMenuList();
},
methods: {
logout() {
window.sessionStorage.clear();
this.$router.push("/login");
},
//获取所有的菜单
async getMenuList(){
const {data:res} = await this.$http.get('menus');
if(res.meta.status !== 200) return this.$message.error(res.meta.msg);
this.menuList = res.data;
console.log(res);
}
},
};
</script>
我们通过接口获取菜单数据,如果获取不成功(status不是200),则弹出错误信息,如果获取成功,将data赋值给设置好的menuList变量。
我们登录后到Home页面,F12查看控制台打印的res对象:
可以看到结构如同API文档中的结构,一共有五个主菜单,其中每个菜单还有子菜单(Array的数量就是子菜单的数量)。
同时,我们可以看到Authorization对象是有值的,证明我们在请求菜单之前,已经试用axios的拦截器将token封装进去了:
三、渲染菜单结构
我们通过API接口获取到了菜单的数据,下面我们就要将菜单的数据渲染到左侧菜单栏,根据层架来加载菜单。
通过接口返回的data结构我们可以分析出,menuList对象的每一个子成员,都是一级菜单,而每一个一级菜单的children对象中,是二级菜单。所以我们使用两层for循环即可,一级for循环加载一级菜单,二级for循环加载二级菜单,实现如下:
<el-container>
<!-- 侧边栏 -->
<el-aside width="200px">
<el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b">
<!-- 一级菜单 -->
<el-submenu :index="item.id+''" v-for="item in menuList" :key="item.id">
<!-- 一级菜单的模板区域 -->
<template slot="title">
<!-- 图标 -->
<i class="el-icon-location"></i>
<!-- 菜单名称 -->
<span>{{item.authName}}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item :index="item.id+'-'+subItem.id" v-for="subItem in item.children" :key="subItem.id">
<template slot="title">
<i class="el-icon-menu"></i>
<span slot="title">{{subItem.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
<!-- 右侧内容主体 -->
<el-main>Main</el-main>
</el-container>
首先是一级for循环,在el-submenu上,这里必须指定index为动态数据,以id为主(因为只接收字符串,所以id后加了空串),这样会避免打开一个菜单时所有菜单一起打开(因为index相同)。然后制定for循环menuList的data数据,key是data成员的id。然后在一级菜单的文本区域设置authName属性。
二级菜单的for循环,在el-menu-item上,循环的是data每个子成员的children属性,同样的设置index和key,以及菜单名。
最终效果:
至此,左侧菜单的加载和渲染就编写完毕了。
下一篇我们继续来美化左侧菜单。
参考:黑马程序员(www.itheima.com)Vue项目实战教学视频
转载请注明出处:https://blog.csdn.net/u013517797/article/details/120611652
以上是关于VUE项目实战17通过接口获取菜单并渲染的主要内容,如果未能解决你的问题,请参考以下文章
vue+vue-router+axios+element-ui构建vue实战项目之七(渲染content.vue内容)
Vue2+VueRouter2+webpack 构建项目实战:配置子路由