需求背景
- 登录后做权限控制,没有权限的用户跳转到无权限页面
- 外网访问做了菜单级别权限控制,有的菜单在外网是不能访问的,需要展示无权限页面
需求分析
针对这两个需求,要做到以下两点:
- 写一个静态页面给后端,登录后让后端跳到这个静态页面的路由,
- 对于菜单级别控制,只能去替换内容区展示,不能影响到页面的地址(所以不能做路由级别控制)
难题
- 接口是子应用的接口返回804,才展示无权限,不是在主应用的接口控制
- 由于之前的项目做了tab切换以及页面的keep-alive,所以当页面来回切换时,是不会请求接口的。
解决方案
- 针对难点1,我考虑是封装一层xhr监听,只要在当前浏览器下展示的页面(不管是主应用还是子应用),所有的ajax请求,都是通过一个xhr的原型对象实例化而来的,所以只要在xhr层进行封装,就完美解决了父子应用不是一个axios的问题。
(function () {
const XHR = XMLHttpRequest.prototype;
const send = XHR.send;
XHR.send = function () {
this.addEventListener('load', function () {
const response = JSON.parse(this.response)
console.log('response', response);
if (response.code == 804) {
return store.commit('login/ADD_NOT_PERMISSION_TAB')
}
})
return send.apply(this, arguments)
}
})();
- 针对tab切换不发送请求的情况,我是在xhr封装的前提下,如果当前子应用页面有804返回,就记录在store中,然后在页面级别写一个computed来进行监听$route
// store
ADD_NOT_PERMISSION_TAB(state) {
// 找到当前的tab的Code
const { activeMenuTab } = state;
// 从tabs列表中找到当前tab的对象
const currentTab = state.menuTabs.find(tab => tab.code === activeMenuTab)
if (currentTab) {
// 存入当前tab的path地址
state.notPermissionTabs.push(currentTab.path.split('?')[0])
}
}
//main.vue
<template>
<not-permission v-show="notPermission"></not-permission>
<!-- micro 子应用页面 -->
<div style="width:100%;height:100%" v-show="!notPermission && mainContainer === 'micro'">
<el-container class="content-wrap" data-id="subapp-viewport" v-for="item in microApps" :key="item.name"
:id="item.name" v-show="$route.path === item.routePath">
</el-container>
</div>
</template>
<script>
computed: {
...mapGetters(['notPermissionTabs']),
notPermission() {
const { fullPath } = this.$route
return this.notPermissionTabs.find(path => path === fullPath.split('?')[0])
},
}
</script>