diff --git a/webui/src/hooks/__tests__/useMessage.test.ts b/webui/src/hooks/__tests__/useMessage.test.ts new file mode 100644 index 00000000..85b2ed25 --- /dev/null +++ b/webui/src/hooks/__tests__/useMessage.test.ts @@ -0,0 +1,18 @@ +/** + * #1145:路由守卫在 app.runWithContext() 中第一次调用 useAuth() → useMessage()。 + * 此时创建的 discrete app 会从外层应用查找 n-message-provider,message 为 undefined, + * 登录成功后 message.success 抛错,跳转不执行。 + */ +import { describe, expect, it } from 'vitest'; +import { createApp } from 'vue'; +import { useMessage } from '@/hooks/useMessage'; + +describe('useMessage', () => { + it('should return a working message API when first called inside app.runWithContext', () => { + const app = createApp({}); + + const message = app.runWithContext(() => useMessage()); + + expect(typeof message?.success).toBe('function'); + }); +}); diff --git a/webui/src/hooks/useMessage.ts b/webui/src/hooks/useMessage.ts index bad2151f..008ca9e0 100644 --- a/webui/src/hooks/useMessage.ts +++ b/webui/src/hooks/useMessage.ts @@ -1,6 +1,5 @@ import { createDiscreteApi } from 'naive-ui'; import type { GlobalThemeOverrides } from 'naive-ui'; -import { createSharedComposable } from '@vueuse/core'; // Soft Ink toast:反色墨条 —— 所有类型同一深底,语义色只出现在图标上。 // (组件级 token 可以用 CSS 变量;只有 common 必须是字面量) @@ -27,9 +26,12 @@ const toastTheme: GlobalThemeOverrides = { }, }; -export const useMessage = createSharedComposable(() => { - const { message } = createDiscreteApi(['message'], { - configProviderProps: { themeOverrides: toastTheme }, - }); - return message; +// 在模块加载时创建:首次调用若发生在路由守卫的 app.runWithContext() 中, +// discrete app 会从外层应用查找 n-message-provider 而失败(#1145)。 +const { message } = createDiscreteApi(['message'], { + configProviderProps: { themeOverrides: toastTheme }, }); + +export function useMessage() { + return message; +}