极少有这种奇怪的需求,去年遇到的,一直没有整理,现在有时间整理了,尴尬的是项目的登录密码忘了。。。没办法调试了。。但是大体的思路是这样的

需求

网站原本有一个菜单列表,现在用户希望点击某行数据的时候,弹出一个新的页面,同时左侧加载一个新的菜单。之前的菜单对应的是项目列表,新菜单对应的是单个项目的各项信息明细。

思路

面对上面这个问题,首先要整理思路:

  1. 数据问题:
    在提出这个需求之前,这就是一个再正常不过的管理端,所以路由也就是针对一个系统一个菜单的路由,即登录成功后从接口抓一下就完事了。因为不想改动太多,所以第二个菜单依旧在之前的菜单管理页面进行添加,但是可以规定一下某个字段只能包含某某某字符,方便我们分离出来;
  2. 分离问题(两个接口的就不用管分离了):
    什么时候分离?数据抓过来之后,绑定到页面上之前都可以(这里建议在菜单数据转化为路由前分离,转化之后再分离好像遇到个奇怪问题,具体的忘了);
  3. 路由问题:
    一般情况下,我们只会进行一次new VueRouter()(至于new两次会怎么样,也没试过),添加路由时也是分开的。
  4. 显示问题:
    弹出的新页面使用第二个菜单目录,意味着我们的母版页面需要新的(什么是母版页面,包含整个页面显示内容的组件);

步骤

  1. 首先熟悉当前项目的路由相关的代码:加载位置,是否格式化数据等;

  2. 先写个固定路由,这些路由可以使用,但不会影响当前目录,所以登录页面的路由在哪里,这些路由就可以写在哪里(当时没主要到有个hidden字段。。。)
    在这里插入图片描述

  3. 如果样式和传递参数的方式相同的话,可以直接复用之前的目录组件;

  4. 复制出来一个新的母版页面,分离路由数据:

computed: {
	menuRoutes() {
		const parentMenu = this.$router.options.routes.filter(val => {
			return val.name === 'singleProject'
		})
		return parentMenu[0].children
	}
}

到这里,静态路由已经实现,接下来是静态路由转为动态路由

  1. 删除之前写好的固定路由,写入到菜单表中;
  2. 分离方式进行变更(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
}
Logo

前往低代码交流专区

更多推荐