Vue 一个网站如何实现两个菜单路由
极少有这种奇怪的需求,去年遇到的,一直没有整理,现在有时间整理了,尴尬的是项目的登录密码忘了。。。没办法调试了。。但是大体的思路是这样的需求网站原本有一个菜单列,现在用户希望点击某行数据的时候,弹出一个新的页面,同时左侧加载一个新的菜单。之前的菜单对应的是项目的各种信息列表,新菜单对应的是单个项目的各项信息明细。步骤首先熟悉当前项目的路由相关的代码:加载位置,是否格式化数据等;先写个固定路由,这些
·
极少有这种奇怪的需求,去年遇到的,一直没有整理,现在有时间整理了,尴尬的是项目的登录密码忘了。。。没办法调试了。。但是大体的思路是这样的
需求
网站原本有一个菜单列表,现在用户希望点击某行数据的时候,弹出一个新的页面,同时左侧加载一个新的菜单。之前的菜单对应的是项目列表,新菜单对应的是单个项目的各项信息明细。
思路
面对上面这个问题,首先要整理思路:
- 数据问题:
在提出这个需求之前,这就是一个再正常不过的管理端,所以路由也就是针对一个系统一个菜单的路由,即登录成功后从接口抓一下就完事了。因为不想改动太多,所以第二个菜单依旧在之前的菜单管理页面进行添加,但是可以规定一下某个字段只能包含某某某字符,方便我们分离出来; - 分离问题(两个接口的就不用管分离了):
什么时候分离?数据抓过来之后,绑定到页面上之前都可以(这里建议在菜单数据转化为路由前分离,转化之后再分离好像遇到个奇怪问题,具体的忘了); - 路由问题:
一般情况下,我们只会进行一次new VueRouter()
(至于new两次会怎么样,也没试过),添加路由时也是分开的。 - 显示问题:
弹出的新页面使用第二个菜单目录,意味着我们的母版页面需要新的(什么是母版页面,包含整个页面显示内容的组件);
步骤
-
首先熟悉当前项目的路由相关的代码:加载位置,是否格式化数据等;
-
先写个固定路由,这些路由可以使用,但不会影响当前目录,所以登录页面的路由在哪里,这些路由就可以写在哪里(当时没主要到有个hidden字段。。。)
-
如果样式和传递参数的方式相同的话,可以直接复用之前的目录组件;
-
复制出来一个新的母版页面,分离路由数据:
computed: {
menuRoutes() {
const parentMenu = this.$router.options.routes.filter(val => {
return val.name === 'singleProject'
})
return parentMenu[0].children
}
}
到这里,静态路由已经实现,接下来是静态路由转为动态路由
- 删除之前写好的固定路由,写入到菜单表中;
- 分离方式进行变更(store中有个一路由的module,需要提前在里面格式化一下数据,新增
minMenuRoutes
属性,用于放置分离的数据,然后在使用的页面再拿出来)
// 这是store里的数据分离,忘记当时是什么原因,让我有重写了一个filterTargetRoutes方法。。。
init(context) {
return new Promise(async resolve => {
if (context.state.menuRoutes.length <= 0) {
let routes = await asyncRoutes.getRoutes()
// 修改开始
let newTargetRoute = routes.filter(val => {
return val.name === 'singleProject'
})
routes = routes.filter(val => {
return val.name !== 'singleProject'
})
// 修改结束
routes = filterAddRoutes(routes)
let addRoutes = []
addRoutes.push(mainRoute)
addRoutes = filterAddRoutes(addRoutes)
addRoutes[0].children = addRoutes[0].children.concat(routes)
addRoutes.push(endRoute)
// 修改开始
newTargetRoute = filterTargetRoutes(newTargetRoute)
addRoutes.push(...newTargetRoute)
// 修改结束
router.addRoutes(addRoutes)
context.commit('setRoutes', routes)
// 修改开始
context.commit('setMinRoutes', newTargetRoute)
// 修改结束
}
resolve()
})
},
// 这里脑抽了,我也不明白为什么当时明明已经在store筛选过一次了,这里还要再筛选一遍。。。
// 难道是怕里面还有个“doubleProject” ??????
// routes是为了直接定位到store下的routes.js这里
...mapState('routes', {
menuRoutes: (state) => {
const parentMenu = state.minMenuRoutes.filter((val) => {
return val.name === 'singleProject'
})
return parentMenu[0].children
}
}),
静态路由转动态路由,两者的区别是动态路由刚从数据库抓过来后,其实只是一个数组,所以需要对其进行转化:格式化方式如下:
// routes:路由数组
export function filterAddRoutes(routes) {
const result = []
routes.forEach(route => {
const tmp = { ...route }
if (tmp.children && tmp.children.length) {
tmp.children = filterAddRoutes(tmp.children)
}
if (tmp.children && tmp.children.length && !tmp.component) {
tmp.component = () => import('@/views/home/nest')
}
if (tmp.children && tmp.children.length && !tmp.redirect) {
tmp.redirect = tmp.children[0].path
}
result.push(tmp)
})
return result
}
// 这是我重写的方法
export function filterTargetRoutes(routes) {
const result = []
routes.forEach(route => {
const tmp = { ...route }
if (tmp.children && tmp.children.length) {
tmp.children = filterAddRoutes(tmp.children)
}
if (tmp.children && tmp.children.length && tmp.path) {
try {
const path = 'modules/' + tmp.path.replace(/(^\/+|\/+$)/g, '')
if (appLib.appUtil.isProduction()) {
tmp.component = () => import('@/views/' + path)
} else {
tmp.component = require('@/views/' + path).default
}
} catch (error) {
console.error(error.message)
// appLib.appUtil.catchError(error)
}
}
if (tmp.children && tmp.children.length && !tmp.redirect) {
tmp.redirect = tmp.children[0].path
}
result.push(tmp)
})
return result
}
更多推荐
已为社区贡献3条内容
所有评论(0)