由于后端不能完全返回导航结构的问题,导致导航权限控制需要前端配合处理。
流程如下: 前端定义好所有的router,通过后端返回数据进行对比处理显示
(此项目中,所要进行的数据处理如下:1.统一前后端对于导航名称的定义 2.不同类型的模块接口项不同)
1.在routers.js 文件中定义好初始路径,通过接口请求数据,然后对数据处理
在此过程中遇到的问题:
1)ajax请求时,引入了二次封装的axios,import axios from "@/libs/axios";结果却报错:
查找很久,没有找到原因,发现引用自带的axios就不会报错,import axios from "axios"; 但是有个问题是,这种情况下不支持跨域请求。所以又单独对这个接口做了封装(仅post方式的),代码如下:
import axios from "axios";
import config from '@/config' // 定义了开发环境和生产环境
import { getToken } from '@/libs/util'
import Qs from 'qs'
const host = location.host // 获取当前用户访问URL主机信息
const srcUrl = host.indexOf('baidu.com')
const ajaxUrl =
process.env.API_PATH === 'live' || srcUrl > -1 ? config.baseUrl.pro : config.baseUrl.uat
// 创建axios实例,防止污染全局
let instance = axios.create({
baseURL: ajaxUrl
})
// 添加请求拦截
instance.interceptors.request.use(
req => {
// 将token存储在sessionStorage里
const token = getToken()
// 在发送请求之前做什么
if (req.method === 'post') {
// 添加post请求参数
if (req.data) {
req.data.vue_token = token
} else {
req.params = {
vue_token: token
}
}
// 如果是post请求,需要设置请求头和转换参数的数据格式
if (!req.headers['Content-type']) {
req.headers['Content-type'] = 'application/x-www-form-urlencoded'
req.data = Qs.stringify(req.data)
}
}
return req
},
() => {
// 对请求错误做些什么
const returnData = {
returndata: {
status: 'error'
}
}
return Promise.resolve(returnData)
}
)
instance.post('/url').then((res) => {
console.log(res)
})
以上 ,是目前遇到的问题,因为耽搁了很久,做个笔记希望下次不会再浪费时间。
开始处理数据,联调接口:
/* 导航对应关系 */
let navChange = {}
// 导航权限
let navRight = {}
// 原始数据
let routes = []
// 数据处理
function dataChange () {
// 获取本地所有导航菜单
for (let i = 0; i < routes.length; i++) {
if (routes[i].children) {
for (let j = 0; j < routes[i].children.length; j++) {
if (routes[i].children[j].children) {
for (let k = 0; k < routes[i].children[j].children.length; k++) {
matchData(routes[i].children[j].children[k].name, i, j, k)
}
}
matchData(routes[i].children[j].name, i, j, '-1')
}
}
matchData(routes[i].name, i, '-1', '-1')
}
console.log(routes)
}
// 匹配替换 前端name a,b,c可以定位name的位置
function matchData (name, a, b, c) {
const change = Object.keys(navChange)
for (let j = 0; j < change.length; j++) {
/* 前端name与后端name对应 */
if (name === change[j]) {
const curSys = navChange[change[j]].type
const curName = navChange[change[j]].name
console.log(navRight[curSys][curName] !== undefined)
console.log(name, a, b, c)
if (navRight[curSys][curName] !== undefined) {
if (curSys === 'sys') {
if (navRight[curSys][curName].delete !== '1') {
if (c === '-1') {
routes[a].meta.access = ['user']
} else if (b === '-1') {
routes[a].children[b].meta.access = ['user']
} else {
routes[a].children[b].children[c].meta.access = ['user']
}
}
}
} else {
if (c === '-1') {
routes[a].meta.access = ['user']
} else if (b === '-1') {
routes[a].children[b].meta.access = ['user']
} else {
routes[a].children[b].children[c].meta.access = ['user']
}
}
}
}
}
console.log('我是输出', routes)
export default routes
结果发现:首先打印的是‘我是输出’。由此终于明白最开始发现的问题(一开始打算在index.js文件中的beforeEach钩子中修改title生效,修改access成功但不生效的原因了)代码执行顺序问题,这里的ajax是异步请求,还没对数据进行处理就已经返回了。接下来将要进行 axios ajax同步请求的设置。
用下面的方法进行修改:
写了一个 async 版本的 简略的代码 这样导出的是一个promise对象
在别的模块中 import 之后 可以在then 方法中获取到值
export default (async () => {
let i18n = await new Promise((resolve, reject) => {
$.ajax({
success(result) {
resolve(new VueI18n({message:{en:result.en}}))
}
})
})
return i18n
})()
=======================================
import i18n from '...i18n'
let i18nData
i18n.then(data => i18nData = data)
经过几天的研究,最终还是觉得无解,export并不会等待我的异步的代码执行结束。
最后还是不得已在用到这个数据的地方再次进行了处理。(本项目中的src\components\main\main.vue文件中)
感觉进了一个坑好久,终于出来了