|
|
|
@ -2,12 +2,12 @@ import Layout from '@/layout' |
|
|
|
import SkeletonPage from '@/view/app/common/SkeletonPage' |
|
|
|
import SkeletonPage from '@/view/app/common/SkeletonPage' |
|
|
|
import Page500 from '@/view/app/500' |
|
|
|
import Page500 from '@/view/app/500' |
|
|
|
import {isEmpty} from "@/util" |
|
|
|
import {isEmpty} from "@/util" |
|
|
|
import {isExternal} from "@/util/validate" |
|
|
|
import {isExternal, isString} from "@/util/validate" |
|
|
|
|
|
|
|
|
|
|
|
//json字符串转路由
|
|
|
|
//json字符串转路由配置
|
|
|
|
export function parseRoutes(str) { |
|
|
|
export function str2routeConfig(str) { |
|
|
|
const parseOpt = (key, value) => { |
|
|
|
const parseOpt = (key, value) => { |
|
|
|
if (key === 'dynamicTitle' && typeof value === 'string') { |
|
|
|
if (key === 'dynamicTitle' && isString(value)) { |
|
|
|
return isEmpty(value) ? undefined : eval(`(${value})`) |
|
|
|
return isEmpty(value) ? undefined : eval(`(${value})`) |
|
|
|
} |
|
|
|
} |
|
|
|
return value |
|
|
|
return value |
|
|
|
@ -15,17 +15,6 @@ export function parseRoutes(str) { |
|
|
|
return JSON.parse(str, parseOpt) |
|
|
|
return JSON.parse(str, parseOpt) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//路由转json字符串
|
|
|
|
|
|
|
|
export function stringifyRoutes(routes) { |
|
|
|
|
|
|
|
const stringifyOpt = (key, value) => { |
|
|
|
|
|
|
|
if (key === 'dynamicTitle' && typeof value === 'function') { |
|
|
|
|
|
|
|
return value.toString() |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return value |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return JSON.stringify(routes, stringifyOpt) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//根据json数组生成路由
|
|
|
|
//根据json数组生成路由
|
|
|
|
export function generateRoutes(jsonTree) { |
|
|
|
export function generateRoutes(jsonTree) { |
|
|
|
//将深度为2的节点合并为由其最末子节点组成的数组
|
|
|
|
//将深度为2的节点合并为由其最末子节点组成的数组
|
|
|
|
@ -56,59 +45,68 @@ export function generateRoutes(jsonTree) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//数据转换,同时剔除不合法的路由(外链、无子节点且无component且非iframe)
|
|
|
|
//数据转换,同时剔除不合法的路由
|
|
|
|
function transform(routes, depth = 1) { |
|
|
|
function transform(routes, depth = 1) { |
|
|
|
|
|
|
|
if (!Array.isArray(routes)) return |
|
|
|
|
|
|
|
|
|
|
|
for (let i = routes.length - 1; i >= 0; i--) { |
|
|
|
for (let i = routes.length - 1; i >= 0; i--) { |
|
|
|
const {path, component, children, meta = {}} = routes[i] |
|
|
|
const {path, component, children, meta = {}} = routes[i] |
|
|
|
|
|
|
|
|
|
|
|
if (isEmpty(component)) { |
|
|
|
//剔除外链节点以及无component且非iframe的节点
|
|
|
|
//剔除外链
|
|
|
|
if (isExternal(path) || !component && !meta.iframe) { |
|
|
|
if (isExternal(path)) { |
|
|
|
|
|
|
|
routes.splice(i, 1) |
|
|
|
routes.splice(i, 1) |
|
|
|
continue |
|
|
|
continue |
|
|
|
} |
|
|
|
} |
|
|
|
delete routes[i].component |
|
|
|
|
|
|
|
|
|
|
|
//清理一些空属性,避免vue-router出错
|
|
|
|
|
|
|
|
['name', 'component', 'meta'].forEach(key => { |
|
|
|
|
|
|
|
if (key in routes[i] && isEmpty(routes[i][key])) { |
|
|
|
|
|
|
|
delete routes[i][key] |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
}) |
|
|
|
//设置路由组件
|
|
|
|
|
|
|
|
if (component.toUpperCase() === 'LAYOUT') { |
|
|
|
//设置路由组件,当component是vue组件声明对象时,不会进行懒加载
|
|
|
|
|
|
|
|
if (component) { |
|
|
|
|
|
|
|
if (isString(component) && component.toUpperCase() === 'LAYOUT') { |
|
|
|
routes[i].component = Layout |
|
|
|
routes[i].component = Layout |
|
|
|
} |
|
|
|
} |
|
|
|
else routes[i].component = lazyLoadView(component) |
|
|
|
else if (isString(component) || typeof component === 'function') { |
|
|
|
|
|
|
|
routes[i].component = lazyLoadView(component) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!children || children.length <= 0) { |
|
|
|
|
|
|
|
//末级节点统一设置props=true,省的动态路由还要手动加
|
|
|
|
|
|
|
|
routes[i].props = true |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
|
|
|
|
//先尝试递归
|
|
|
|
transform(children, depth + 1) |
|
|
|
transform(children, depth + 1) |
|
|
|
|
|
|
|
|
|
|
|
//如果子级被清空,并且无component且非iframe
|
|
|
|
//叶子节点统一设置props = true,省的动态路由还要手动加
|
|
|
|
if (children.length <= 0 && !meta.iframe) { |
|
|
|
if (!children || children.length <= 0) { |
|
|
|
routes.splice(i, 1) |
|
|
|
routes[i].props = true |
|
|
|
continue |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//设置根节点的redirect
|
|
|
|
//设置根节点的redirect
|
|
|
|
if (depth === 1) { |
|
|
|
else if (depth === 1) { |
|
|
|
let rootPath = path |
|
|
|
const rootPath = path.endsWith('/') ? path : `${path}/` |
|
|
|
if (!rootPath.endsWith('/')) rootPath += '/' |
|
|
|
|
|
|
|
routes[i].redirect = `${rootPath}${children[0].path}` |
|
|
|
routes[i].redirect = `${rootPath}${children[0].path}` |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//路由页面懒加载
|
|
|
|
//路由页面懒加载,入参可以是字符串、返回值为Promise的函数
|
|
|
|
function lazyLoadView(path) { |
|
|
|
function lazyLoadView(component) { |
|
|
|
if (path.endsWith('/')) path += 'index' |
|
|
|
if (isString(component)) { |
|
|
|
else if (path.endsWith('Page')) path = path.replace('Page', '') |
|
|
|
if (component.endsWith('/')) { |
|
|
|
else path = path.replace('Page.vue', '') |
|
|
|
component += 'index' |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else if (component.endsWith('Page')) { |
|
|
|
|
|
|
|
component = component.replace('Page', '') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
component = component.replace('Page.vue', '') |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//这里注意一点,如果设置了超时时间,那么超时后只能刷新整个页面才能重新加载该组件
|
|
|
|
//这里注意一点,如果设置了超时时间,那么超时后只能刷新整个页面才能重新加载该组件
|
|
|
|
const AsyncHandler = () => ({ |
|
|
|
const AsyncHandler = () => ({ |
|
|
|
component: import(`@/view/${path}Page.vue`), |
|
|
|
component: typeof component === 'function' ? component() : import(`@/view/${component}Page.vue`), |
|
|
|
loading: SkeletonPage, |
|
|
|
loading: SkeletonPage, |
|
|
|
error: Page500, |
|
|
|
error: Page500, |
|
|
|
delay: 200, |
|
|
|
delay: 200, |
|
|
|
@ -116,6 +114,7 @@ export function generateRoutes(jsonTree) { |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
return () => Promise.resolve({ |
|
|
|
return () => Promise.resolve({ |
|
|
|
|
|
|
|
abstract: true, |
|
|
|
functional: true, |
|
|
|
functional: true, |
|
|
|
render(h, {data, children}) { |
|
|
|
render(h, {data, children}) { |
|
|
|
return h(AsyncHandler, data, children) |
|
|
|
return h(AsyncHandler, data, children) |
|
|
|
|