共计 2633 个字符,预计需要花费 7 分钟才能阅读完成。
/*
约定:
通过目录后果生产路由信息
目录构造如下
目录 1 -- 目录 2 -- 目录 3 -- 页面
生成的路由 path 是: 目录 1 / 目录 2 / 目录 3 / 页面
如果页面用 index.vue 命名, path 会被截取, 生成: 目录 1 / 目录 2 / 目录 3
举荐的目录层级如下
业务目录
-- 模块目录
-- 页面
此时生成的 path 为: 业务目录 / 模块目录 / 页面, 同时应用 Layout 布局 (蕴含菜单和导航)
当 path 只有一层时, 将不应用 Layout 布局, 如
页面目录 (home)
-- 页面 (命名 index.vue)
目录中含有 components 的文件不会生成路由信息
*/
// 首页不须要 Layout
// 重定向
// 404
// views 为 src 下页面所在的目录
// 获取所有的路由信息
let allFiles = []
const contexts = require.context(
'@/views',
true,
/^(?!.*?components).*\.vue$/,
'lazy',
)
contexts.keys().forEach(file => {allFiles.push(file)
})
// console.log('allFiles', allFiles)
import Layout from '@/layout/Layout2'
let routes = []
allFiles.forEach(file => {
let path = file
.substring(1)
.replace('/index.vue', '')
.replace('.vue', '')
let name = path.substring(1).replace(/\//g, '-')
let _filePath = file.replace('./', '')
let component = loader(_filePath)
// console.log(path)
let array = path.split('/')
// console.log(array.length, path)
if (array.length < 2) {return}
// 目前一层目录不必 Layout
if (array.length === 2) {
let route = {
path,
component,
name,
}
routes.push(route)
return
}
path = path.replace(`/${array[1]}/`, '')
// fullScreen 不加 layout
if (array[1] === 'fullScreen') {
let route = {path: `/fullScreen/${path}`,
component,
name,
}
routes.push(route)
} else {
// 多层目录套用 Layout
let route = {path: `/${array[1]}`,
component: Layout,
children: [{path, component, name}],
}
routes.push(route)
}
})
const redirect = [
// 页面首页重定向
{
path: '/',
redirect: '/home',
},
{
path: '/502',
redirect: '/fullScreen/502',
},
// 404
{
path: '*',
redirect: '/fullScreen/404',
},
]
// 增加重定向
routes.push(...redirect)
// console.log('routes', routes)
// import(// /* webpackChunkName: '[request]' */
// `@/views/${file}`
// )
function loader(file) {return () => import(`@/views/${file}`)
}
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export let router = new Router({
// mode: 'history',
scrollBehavior: () => ({ y: 0}),
routes: routes,
})
import store from '@/store/index'
router.beforeEach((to, from, next) => {
// 避免用户手动去清导航的本地存储
if (!localStorage.getItem('boxCategoryDataLocal')) {localStorage.setItem('boxCategoryDataLocal', '21212')
next({path: '/'})
return
}
// 当 url 切换时, 切换上下文, 从 url 中取出上下文, 并且切换上下文
let contextName = to.path.split('/')[1]
if (store.getters.allContainers[contextName] &&
contextName !== store.getters.currentContainer.contextName
) {store.dispatch('changeContext', contextName)
next()
return
}
// 一些公共页面如 common, 是找到不到对应的 container 对象的
// 此时也不会切换上下文, 目前不做任何解决
next()})
import {Modal} from 'view-design'
router.onError(error => {console.log('发版错误码:', error.message)
const pattern = /Loading chunk (.)+ failed/g
const isChunkLoadFailed = error.message.match(pattern)
if (isChunkLoadFailed) {
Modal.error({
title: '提醒',
content: '网站有更新,请刷新页面',
okText: '刷新',
onOk: () => {location.reload()
},
})
}
})
// 修复在跳转时 push 了雷同的地址会报错的问题
const originalPush = Router.prototype.push
Router.prototype.push = function push(location) {return originalPush.call(this, location).catch(err => err)
}
正文完