因为路由规则需要全局存放,所以如何通过store来完成操作?
关于state
// store/router.js
const state = {
// 做一个记录而已
routes: [],
asyncRoutes: [],
}
这里需要记录两个东西,一个是routes,这是记录这个用户所具有的访问的路由权限,只是个记录而已,
另外一个是记录格式完后的从后端请求回来的规则。
关于mutation
const mutations = {
/**
* @param {*} state
* @param {arr} routes 格式完后的路由规则
*/
SET_ROUTES: (state, routes) => {
state.asyncRoutes = routes
state.routes = initRoutes.concat(routes)
},
RESET_ROUTES: (state) => {
// 把记录设置为空
state.asyncRoutes = []
state.routes = []
},
}
在讲action部分之前,需要讲如何把之前格式化的代码封装一下。
/**
* @param {Array} arr 传后端返回的路由规则的数组
*/
function parseRoutes(arr) {
let newArr = []
arr.forEach((item) => {
let newItem = Object.assign({}, item)
let str = item.component
//"/page1.vue"=>import("@/views/page1.vue")
// 格式化规则
newItem.component = () => {
// return require([`@/views${_str}`],resolve)
return import(`@/views${str}`)
}
newArr.push(newItem)
})
return newArr
}
关于action
const actions = {
getRoutes: ({ commit }) => {
let id = Cookies.get('id')
if (id) {
let menu = JSON.parse(localStorage.getItem("menu"))
return new Promise((resolve)=>{
if(menu){
let newArr = parseRoutes(menu)
commit('SET_ROUTES', newArr)
resolve(newArr)
}else{
axios.get(`http://localhost:3000/router/1000`).then((res) => {
// console.log(res.data);
localStorage.setItem('menu', JSON.stringify(res.data))
let newArr = parseRoutes(res.data)
// console.log(newArr);
commit('SET_ROUTES', newArr)
resolve(newArr)
})
}
})
}
},
resetRoutes:({commit})=>{
resetRouter()
commit('RESET_ROUTES')
}
}
以上有点复杂,拆开看逻辑
// 1. 首先获取到存放的id
let id = Cookies.get('id')
// 2. 然后根据id进行判断,不存在没有id的情况,这会在之后的整体流程分析讲到。
if(id){}
// 3. 如果id存在,还需要进行判断
// 因为在请求完规则后,会把这个规则放到loaclStorage,下次用户登录的话还会存在,直接用就行了。
axios.get(`http://localhost:3000/router/1000`).then((res) => {
// console.log(res.data);
localStorage.setItem('menu', JSON.stringify(res.data))
})
// 4. 判断存放的menu是否存在,来进行解析和存放操作
if(menu){
let newArr = parseRoutes(menu)
commit('SET_ROUTES', newArr)
resolve(newArr)
}else{
axios.get(`http://localhost:3000/router/1000`).then((res) => {
// console.log(res.data);
localStorage.setItem('menu', JSON.stringify(res.data))
let newArr = parseRoutes(res.data)
// console.log(newArr);
commit('SET_ROUTES', newArr)
resolve(newArr)
})
}
最后,因为axios请求是异步操作,所以这个action要返回格式化完的路由,需要通过new Promise的形式,通过resolve来返回,这就是你们所看到的这里出现了Promise。
resetRoutes这个action就不用说了把,就是把两个记录一些内容的state删除掉就行了。
顺便提一下这里记录有用途。第一,方便通过vue-tool工具进行查看,第二,可以在后面讲路由守卫的判断中用到。