improve type safety and simplify dynamic route registration

This commit is contained in:
jingrow 2025-11-21 13:13:35 +08:00
parent 712bb7242d
commit 06283becab
2 changed files with 19 additions and 21 deletions

View File

@ -1,5 +1,6 @@
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'
import type { Router } from 'vue-router'
import { t } from '../i18n'
import { registerToolRoute, unregisterToolRoute, syncToolRoutes, registerAllToolRoutes } from '../utils/dynamicRoutes'
@ -23,6 +24,9 @@ export interface Tool {
author?: string
rating?: number
downloads?: number
// 路由相关(可选,用于动态路由注册)
componentPath?: string // 组件路径(相对于 src/views
routePath?: string // 路由路径(如 'tools/my-tool'
}
const STORAGE_KEY = 'tools.userItems'
@ -121,7 +125,7 @@ export const useToolsStore = defineStore('tools', () => {
})
// 添加用户工具
function addUserTool(tool: Tool, router?: any, componentPath?: string) {
function addUserTool(tool: Tool, router?: Router, componentPath?: string) {
const defaultToolsCount = getDefaultTools().filter(
t => !hiddenDefaultToolIds.value.includes(t.id)
).length
@ -147,7 +151,7 @@ export const useToolsStore = defineStore('tools', () => {
}
// 删除用户工具
function deleteUserTool(toolId: string, router?: any) {
function deleteUserTool(toolId: string, router?: Router) {
const tool = userTools.value.find(t => t.id === toolId)
userTools.value = userTools.value.filter(t => t.id !== toolId)
@ -195,12 +199,12 @@ export const useToolsStore = defineStore('tools', () => {
}
// 初始化工具路由(在应用启动时调用)
function initToolRoutes(router: any) {
function initToolRoutes(router: Router) {
registerAllToolRoutes(router, userTools.value)
}
// 同步工具路由(移除不存在的,添加新的)
function syncRoutes(router: any) {
function syncRoutes(router: Router) {
syncToolRoutes(router, userTools.value)
}

View File

@ -33,12 +33,12 @@ export function registerToolRoute(
// 3. 默认使用 tools/{routeName}.vue
const finalComponentPath =
componentPath ||
(tool as any).componentPath ||
tool.componentPath ||
`../../views/tools/${tool.routeName}.vue`
// 构建路由路径
// 默认使用 tools/{id},但可以通过 tool.routePath 自定义
const routePath = (tool as any).routePath || `tools/${tool.id}`
const routePath = tool.routePath || `tools/${tool.id}`
// 创建路由配置,添加组件加载错误处理
const route: RouteRecordRaw = {
@ -48,10 +48,8 @@ export function registerToolRoute(
console.error(`Failed to load tool component: ${finalComponentPath}`, error)
// 返回一个简单的错误组件
return {
template: '<div style="padding: 20px; text-align: center;"><h3>Component Not Found</h3><p>Failed to load: {{ path }}</p></div>',
data() {
return { path: finalComponentPath }
}
name: 'ToolComponentError',
template: '<div style="padding: 20px; text-align: center;"><h3>Component Not Found</h3><p>Failed to load component</p></div>'
}
}),
meta: {
@ -63,18 +61,14 @@ export function registerToolRoute(
try {
// 将路由添加到 AppLayout 的 children 下
// 如果 AppLayout 路由不存在,尝试添加到根路由
if (router.hasRoute('AppLayout')) {
router.addRoute('AppLayout', route)
// AppLayout 路由应该在应用启动时已存在
const parentRouteName = router.hasRoute('AppLayout') ? 'AppLayout' : null
if (parentRouteName) {
router.addRoute(parentRouteName, route)
} else {
// 查找父路由path 为 '/' 的路由)
const parentRoute = router.getRoutes().find((r: any) => r.path === '/' && r.name !== 'Login')
if (parentRoute) {
router.addRoute(parentRoute.name || parentRoute.path, route)
} else {
// 如果找不到父路由,直接添加到根路由
router.addRoute(route)
}
// 如果 AppLayout 不存在,直接添加到根路由(不应该发生,但作为降级方案)
console.warn('AppLayout route not found, adding tool route to root')
router.addRoute(route)
}
console.log(`Tool route registered: ${tool.routeName} -> ${routePath}`)
return true