前端动态菜单配置(Vue2 / 3 TS)
配置菜单说起来简单, 填写一下菜单路径即可, 但是总容易忘一些东西, 写了文档也没人看, 故而写了这么个小工具简化配置
先说Vite处理方式
utility-type.d.ts
/**
* 基础树状结构
*/
export type BasicTree<T extends Record<any, any> = any> = {
children?: BasicTree<T>[]
} & T
views-scan.ts
import type {BasicTree} from '#/utility-type'
export type ViewsTree = BasicTree<{ label: string, value: string }>
export class ViewsScan {
static tree() {
const baseDir = '/src/views/'
// 扫描views下所有的.vue文件
const fileList = Object.keys(import.meta.glob('@/views/**/*.vue'))
.map(it => it.replace(baseDir, ''))
.sort((a, b) => a.localeCompare(b))
// 将文件列表转换为树状结构
return this.#arrayToTree(fileList)
}
static #arrayToTree(array: string[]): ViewsTree[] {
const tree: ViewsTree[] = []
array.forEach(path => {
const pathArr = path.split('/')
let cursor = tree
pathArr.forEach((label, index) => {
if (index === pathArr.length - 1) {
cursor.push({label: label, value: path})
} else {
let child = cursor.find(node => node.label === label)
!child && cursor.push(child = {label, value: pathArr.slice(0, index + 1).join('/')})
cursor = child.children || (child.children = [])
}
})
})
return tree
}
}
test.vue
<template>
<div>
<el-tree-select v-model="value" :data="data"/>
</div>
</template>
<script lang="ts" setup>
import {ref} from 'vue'
import {ViewsScan} from '@/util/views-scan'
const data = ViewsScan.tree()
const value = ref(null)
</script>
再说一下vue2 cli项目
只需要将views-scan.ts
中import.meta.glob
扫描包的方式修改为下方方式即可
static tree() {
const baseDir = '/src/views/'
// 扫描views下所有的.vue文件
const fileList = require.context(
// 其组件目录的相对路径
baseDir,
// 是否查询其子目录
true,
// 匹配基础组件文件名的正则表达式
/\\*.vue/
).keys()
.map(it => it.replace(baseDir, ''))
.sort((a, b) => a.localeCompare(b))
// 将文件列表转换为树状结构
return this.#arrayToTree(fileList)
}
如果用js的话稍微转换一下即可
题外话
可以将含有component路径的文件过滤一下, 方便一些