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 { defineStore } from 'pinia'
import { computed, ref } from 'vue' import { computed, ref } from 'vue'
import type { Router } from 'vue-router'
import { t } from '../i18n' import { t } from '../i18n'
import { registerToolRoute, unregisterToolRoute, syncToolRoutes, registerAllToolRoutes } from '../utils/dynamicRoutes' import { registerToolRoute, unregisterToolRoute, syncToolRoutes, registerAllToolRoutes } from '../utils/dynamicRoutes'
@ -23,6 +24,9 @@ export interface Tool {
author?: string author?: string
rating?: number rating?: number
downloads?: number downloads?: number
// 路由相关(可选,用于动态路由注册)
componentPath?: string // 组件路径(相对于 src/views
routePath?: string // 路由路径(如 'tools/my-tool'
} }
const STORAGE_KEY = 'tools.userItems' 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( const defaultToolsCount = getDefaultTools().filter(
t => !hiddenDefaultToolIds.value.includes(t.id) t => !hiddenDefaultToolIds.value.includes(t.id)
).length ).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) const tool = userTools.value.find(t => t.id === toolId)
userTools.value = userTools.value.filter(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) registerAllToolRoutes(router, userTools.value)
} }
// 同步工具路由(移除不存在的,添加新的) // 同步工具路由(移除不存在的,添加新的)
function syncRoutes(router: any) { function syncRoutes(router: Router) {
syncToolRoutes(router, userTools.value) syncToolRoutes(router, userTools.value)
} }

View File

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