约定大于配置
在工程化项目中,约定大于配置能节省很多重复代码的编写,故先约定视图的创建规范:
-
首页放在
views/index.vue
路径中。 -
当需要新建视图时,以视图名创建一个目录,例如
views/resource-link
(视图名遵循短横杠法),再在目录下新建index.vue
文件当作视图。 -
参考小程序的做法,对应地在每个同级
index.vue
下新建page.ts
文件,用来配置路由的meta
,例如:export default { title: '主页' }
短横杠命名法:单词首字母小写,单词之间以短横杠分隔。
目录结构参考图
router.ts
Vue Router 的配置代码如下,复制即可:
import { createRouter } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
const pageModules = import.meta.glob('../views/**/page.ts', {
eager: true,
import: 'default'
})
const componentModules = import.meta.glob('../views/**/index.vue', {
eager: true,
import: 'default'
})
const routes = Object.entries(pageModules).map(([pagePath, config]) => {
const path = pagePath.replace('../views', '').replace('/page.ts', '') || '/'
const name = path.split('/').filter(Boolean).join('-') || 'index'
const compoentPath = pagePath.replace('page.ts', 'index.vue')
return {
path,
name,
component: componentModules[compoentPath],
meta: config
}
})
const routeMap: Map<string, RouteRecordRaw> = new Map()
routes.forEach((route: any) => {
const title = route.meta.title
routeMap.set(title, route)
})
const router = createRouter({
// ...
routes: Array.from(routeMap.values())
})
router.beforeEach(async (to, from, next) => {
const baseTitle = '网站名'
if (to.meta.title) {
document.title = `${to.meta.title} - ${baseTitle}`
} else {
document.title = baseTitle
}
// ...
next()
})
export default router
// 在其他组件中需要跳转视图时,通过 getpath(title) 来动态获取 path,例如 getpath('登录')
export const getPath = (title: string): string => {
return routeMap.get(title)?.path || '/'
}
参考资料
[1] 渡一机构. 在vite中使用glob完成自动化导入【渡一教育】[Z/OL]. https://www.bilibili.com/video/BV1xw411K7Zz. 2023.