110 lines
3.2 KiB
JavaScript
110 lines
3.2 KiB
JavaScript
/**
|
|
* 通用的别名路径解析工具
|
|
* 用于在动态导入时解析 @ 别名路径
|
|
*/
|
|
|
|
// 使用 import.meta.glob 预加载所有组件
|
|
const viewsModules = import.meta.glob('../views/**/*.vue');
|
|
|
|
// 创建路径映射表
|
|
const pathMap = new Map();
|
|
|
|
// 初始化路径映射
|
|
Object.keys(viewsModules).forEach(relativePath => {
|
|
// relativePath: ../views/dashboard/index.vue
|
|
|
|
// 1. 别名格式: @/views/dashboard/index.vue
|
|
const aliasPath = relativePath.replace('../views', '@/views');
|
|
pathMap.set(aliasPath, viewsModules[relativePath]);
|
|
|
|
// 2. 数据库格式: /dashboard/index.vue
|
|
const dbPath = relativePath.replace('../views/', '/');
|
|
pathMap.set(dbPath, viewsModules[relativePath]);
|
|
|
|
// 3. 相对路径格式: dashboard/index.vue
|
|
const relativePathFormat = relativePath.replace('../views/', '');
|
|
pathMap.set(relativePathFormat, viewsModules[relativePath]);
|
|
|
|
// 4. 原始相对路径也保留
|
|
pathMap.set(relativePath, viewsModules[relativePath]);
|
|
});
|
|
|
|
/**
|
|
* 解析别名路径为实际模块加载器
|
|
* @param {string} path - 支持的路径格式:
|
|
* - @/views/dashboard/index.vue (别名格式)
|
|
* - /dashboard/index.vue (数据库格式,带前导斜杠)
|
|
* - dashboard/index.vue (相对格式)
|
|
* @returns {Function|null} 返回模块加载器函数,找不到时返回 null
|
|
*/
|
|
export function resolveComponent(path) {
|
|
if (!path) {
|
|
return null;
|
|
}
|
|
|
|
// 尝试多种路径格式
|
|
const searchPaths = [
|
|
path, // 原始路径
|
|
// 如果是以 / 开头的数据库格式,转换为别名格式
|
|
path.startsWith('/') && !path.startsWith('@/') ? `@/views${path}` : null,
|
|
// 如果是相对路径但不在 views 下,添加 @/views 前缀
|
|
!path.includes('@') && !path.includes('/views') && !path.startsWith('/')
|
|
? `@/views/${path}`
|
|
: null,
|
|
].filter(Boolean);
|
|
|
|
// 遍历所有可能的路径格式
|
|
for (const searchPath of searchPaths) {
|
|
const loader = pathMap.get(searchPath);
|
|
if (loader) {
|
|
return loader;
|
|
}
|
|
}
|
|
|
|
// 如果精确匹配失败,尝试模糊匹配(按文件名)
|
|
const fileName = path.split('/').pop();
|
|
for (const [mappedPath, loader] of pathMap.entries()) {
|
|
if (mappedPath.endsWith(fileName)) {
|
|
return loader;
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* 创建组件加载器
|
|
* @param {string} componentPath - 组件路径
|
|
* @returns {Function} Vue 路由组件加载函数
|
|
*/
|
|
export function createComponentLoader(componentPath) {
|
|
const loader = resolveComponent(componentPath);
|
|
|
|
if (loader) {
|
|
return loader;
|
|
}
|
|
|
|
// 找不到组件时,返回一个占位组件
|
|
console.warn(`⚠️ 组件未找到: ${componentPath}`);
|
|
return () => Promise.resolve({
|
|
default: {
|
|
template: `
|
|
<div style="padding: 40px; text-align: center; color: #999;">
|
|
<h3>组件加载失败</h3>
|
|
<p>路径: ${componentPath}</p>
|
|
<p style="font-size: 12px; margin-top: 10px;">请检查组件文件是否存在</p>
|
|
</div>
|
|
`
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* 获取所有已加载的模块路径(用于调试)
|
|
* @returns {Array<string>} 所有可用的路径列表
|
|
*/
|
|
export function getAllModulePaths() {
|
|
return Array.from(pathMap.keys());
|
|
}
|
|
|