@ubean/client 0.4.4 → 0.4.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{app-DiXW_14_.js → app-Bt-2meGm.js} +17 -10
- package/dist/{app-BQgi-8Qp.d.ts → app-emLZM9XN.d.ts} +16 -6
- package/dist/app.d.ts +1 -1
- package/dist/app.js +1 -1
- package/dist/define-app-RzHOZlYB.d.ts +179 -0
- package/dist/define-app.d.ts +1 -167
- package/dist/define-app.js +10 -6
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/ssr.d.ts +1 -1
- package/dist/ssr.js +1 -0
- package/package.json +7 -7
|
@@ -48,19 +48,24 @@ function createUbeanRouter(options) {
|
|
|
48
48
|
const router = createRouter({
|
|
49
49
|
history,
|
|
50
50
|
routes: options.routes,
|
|
51
|
-
scrollBehavior
|
|
52
|
-
if (savedPosition) return savedPosition;
|
|
53
|
-
if (_to.hash) return {
|
|
54
|
-
el: _to.hash,
|
|
55
|
-
behavior: "smooth"
|
|
56
|
-
};
|
|
57
|
-
return { top: 0 };
|
|
58
|
-
}
|
|
51
|
+
scrollBehavior: options.scrollBehavior ?? defaultScrollBehavior
|
|
59
52
|
});
|
|
60
53
|
if (options.setup) options.setup(router);
|
|
61
54
|
if (options.ssr && options.initialUrl) router.push(options.initialUrl);
|
|
62
55
|
return router;
|
|
63
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* 默认滚动策略:返回顶部;带 hash 时仅在目标元素已存在时平滑滚动,
|
|
59
|
+
* 否则返回 `false`(跳过滚动,避免 VUE_ROUTER_R0042 告警)。
|
|
60
|
+
*/
|
|
61
|
+
function defaultScrollBehavior(to, _from, savedPosition) {
|
|
62
|
+
if (savedPosition) return savedPosition;
|
|
63
|
+
if (to.hash) return typeof document !== "undefined" && document.querySelector(to.hash) ? {
|
|
64
|
+
el: to.hash,
|
|
65
|
+
behavior: "smooth"
|
|
66
|
+
} : false;
|
|
67
|
+
return { top: 0 };
|
|
68
|
+
}
|
|
64
69
|
//#endregion
|
|
65
70
|
//#region src/page-macro.ts
|
|
66
71
|
function definePage(_meta) {}
|
|
@@ -185,7 +190,8 @@ function createUbeanClientApp(options) {
|
|
|
185
190
|
const router = createUbeanRouter({
|
|
186
191
|
routes: options.routes,
|
|
187
192
|
ssr: false,
|
|
188
|
-
setup: options.
|
|
193
|
+
setup: options.router?.setup,
|
|
194
|
+
scrollBehavior: options.router?.scrollBehavior
|
|
189
195
|
});
|
|
190
196
|
const { LayoutView: ClientLayoutWrapper, loadLayoutsForRoute: loadClientLayouts } = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
|
|
191
197
|
initCachedViewsFromRoutes(options.routes);
|
|
@@ -223,7 +229,8 @@ function createUbeanSSRApp(initialPage, options) {
|
|
|
223
229
|
routes: options.routes,
|
|
224
230
|
ssr: true,
|
|
225
231
|
initialUrl: initialPage.url,
|
|
226
|
-
setup: options.
|
|
232
|
+
setup: options.router?.setup,
|
|
233
|
+
scrollBehavior: options.router?.scrollBehavior
|
|
227
234
|
});
|
|
228
235
|
const { LayoutView: SsrLayoutWrapper, loadLayoutsForRoute: loadSsrLayouts } = createLayoutWrapper(options.resolveLayoutComponent, options.defaultLayout || null);
|
|
229
236
|
initCachedViewsFromRoutes(options.routes);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { i as RouterConfig } from "./define-app-RzHOZlYB.js";
|
|
1
2
|
import { App, Component } from "vue";
|
|
2
|
-
import { RouteRecordRaw, Router } from "vue-router";
|
|
3
|
+
import { RouteRecordRaw, Router, RouterOptions } from "vue-router";
|
|
3
4
|
import { ERROR_KEY as ERROR_KEY$1, LAYOUT_CHAIN_KEY, LOADING_KEY as LOADING_KEY$1, LOCALIZE_PATH_KEY as LOCALIZE_PATH_KEY$1, LayoutChainContext, LayoutChainRenderer as LayoutChainRenderer$1, Link, PAGE_KEY as PAGE_KEY$1, PageMeta, PageView, SSR_KEY as SSR_KEY$1, SlotView, TRANSITION_KEY as TRANSITION_KEY$1, UbeanVueOptions, ViewTransitionOptions, ubeanVue, useViewTransition } from "@ubean/vue";
|
|
4
5
|
import { VueHeadClient, useHead as useUnheadHead, useSeoMeta } from "@unhead/vue";
|
|
5
6
|
import { PageObject } from "@ubean/pages";
|
|
@@ -21,6 +22,15 @@ interface CreateUbeanRouterOptions {
|
|
|
21
22
|
* 该回调在 Client 和 SSR 环境都会执行。
|
|
22
23
|
*/
|
|
23
24
|
setup?: (router: Router) => void;
|
|
25
|
+
/**
|
|
26
|
+
* vue-router `scrollBehavior`,覆盖默认滚动策略。
|
|
27
|
+
*
|
|
28
|
+
* 默认行为:返回顶部;带 hash 时仅当目标元素已存在才平滑滚动。
|
|
29
|
+
* 客户端延迟生成的锚点(如 SSR 后由客户端渲染的标题 id)在首次导航时
|
|
30
|
+
* 可能尚不存在,直接返回 `{ el }` 会触发 VUE_ROUTER_R0042,因此默认
|
|
31
|
+
* 先探测元素存在性。
|
|
32
|
+
*/
|
|
33
|
+
scrollBehavior?: RouterOptions['scrollBehavior'];
|
|
24
34
|
}
|
|
25
35
|
declare function createUbeanRouter(options: CreateUbeanRouterOptions): Router;
|
|
26
36
|
//#endregion
|
|
@@ -65,12 +75,12 @@ interface UbeanAppOptions {
|
|
|
65
75
|
viewTransitions?: boolean | ViewTransitionOptions;
|
|
66
76
|
hydrate?: boolean;
|
|
67
77
|
/**
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
78
|
+
* router 配置(setup 守卫 + scrollBehavior 等初始化选项)。
|
|
79
|
+
* Client 和 SSR 都会执行;setup 注册守卫必须同步完成。
|
|
80
|
+
* 来自 `defineApp({ router })`,由 `virtual:ubean-app` / `virtual:ubean-server`
|
|
81
|
+
* 在调用本工厂前通过 `resolveAppConfig()` 合并注入。
|
|
72
82
|
*/
|
|
73
|
-
|
|
83
|
+
router?: RouterConfig;
|
|
74
84
|
/**
|
|
75
85
|
* 页面加载时的 fallback 组件,在 SPA 导航懒加载页面组件期间显示。
|
|
76
86
|
* 来源:`pages/loading.vue` 自动检测 或 `defineApp({ loadingComponent })` 显式配置。
|
package/dist/app.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, S as useViewTransition, T as definePage, _ as createUbeanClientApp, a as LOCALIZE_PATH_KEY, b as useSeoMeta, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, k as createUbeanRouter, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead, y as ubeanVue } from "./app-
|
|
1
|
+
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, S as useViewTransition, T as definePage, _ as createUbeanClientApp, a as LOCALIZE_PATH_KEY, b as useSeoMeta, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, k as createUbeanRouter, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead, y as ubeanVue } from "./app-emLZM9XN.js";
|
|
2
2
|
export { type CreateUbeanRouterOptions, ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, type LayoutChainContext, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, UbeanAppInstance, UbeanAppOptions, type UbeanVueOptions, type UbeanVuePage, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useSeoMeta, useViewTransition };
|
package/dist/app.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, a as LOCALIZE_PATH_KEY, b as defineMiddleware, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useSeoMeta, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useViewTransition, x as definePage, y as defineMeta } from "./app-
|
|
1
|
+
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, a as LOCALIZE_PATH_KEY, b as defineMiddleware, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useSeoMeta, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useViewTransition, x as definePage, y as defineMeta } from "./app-Bt-2meGm.js";
|
|
2
2
|
export { ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useSeoMeta, useViewTransition };
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { App, Component, Plugin } from "vue";
|
|
2
|
+
import { Router, RouterOptions } from "vue-router";
|
|
3
|
+
import { ViewTransitionOptions } from "@ubean/vue";
|
|
4
|
+
import { PageHead } from "@ubean/shared";
|
|
5
|
+
//#region src/define-app.d.ts
|
|
6
|
+
interface AppPluginConfig {
|
|
7
|
+
plugin: Plugin | [Plugin, ...any[]];
|
|
8
|
+
mode?: 'all' | 'client' | 'server';
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Router 钩子配置 — 暴露 vue-router 的导航守卫注册入口 + 初始化选项。
|
|
12
|
+
*
|
|
13
|
+
* `setup(router)` 在 router 实例创建后、`app.use(router)` 之前调用,
|
|
14
|
+
* 因此守卫能拦截首次导航(包括 SSR 的初始 URL push)。
|
|
15
|
+
*
|
|
16
|
+
* Client 和 SSR 都会执行,适合做鉴权、埋点、进度条等逻辑。
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* defineApp({
|
|
21
|
+
* router: {
|
|
22
|
+
* setup(router) {
|
|
23
|
+
* router.beforeEach((to, from) => {
|
|
24
|
+
* if (to.meta.requiresAuth && !isAuthenticated()) {
|
|
25
|
+
* return '/login';
|
|
26
|
+
* }
|
|
27
|
+
* });
|
|
28
|
+
* router.afterEach((to) => {
|
|
29
|
+
* analytics.track('page_view', { path: to.fullPath });
|
|
30
|
+
* });
|
|
31
|
+
* },
|
|
32
|
+
* scrollBehavior(to, from, savedPosition) {
|
|
33
|
+
* // 覆盖默认滚动策略(默认已守卫 hash 目标元素不存在时的 R0042)
|
|
34
|
+
* if (savedPosition) return savedPosition;
|
|
35
|
+
* if (to.hash) return { el: to.hash, behavior: 'smooth' };
|
|
36
|
+
* return { top: 0 };
|
|
37
|
+
* }
|
|
38
|
+
* }
|
|
39
|
+
* });
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
interface RouterConfig {
|
|
43
|
+
/**
|
|
44
|
+
* 在 router 创建后、初始导航前调用。
|
|
45
|
+
* 用于注册 `beforeEach` / `beforeResolve` / `afterEach` 等守卫。
|
|
46
|
+
*
|
|
47
|
+
* 注意:setup 必须同步注册守卫(虽然守卫本身可以返回 Promise)。
|
|
48
|
+
* 不要在 setup 中执行异步操作(如请求 API),因为这会延迟首次导航。
|
|
49
|
+
*/
|
|
50
|
+
setup?: (router: Router) => void;
|
|
51
|
+
/**
|
|
52
|
+
* vue-router `scrollBehavior`,覆盖 `createUbeanRouter` 的默认滚动策略。
|
|
53
|
+
* 未配置时使用框架默认:回到顶部;带 hash 且目标元素存在时平滑滚动。
|
|
54
|
+
*/
|
|
55
|
+
scrollBehavior?: RouterOptions['scrollBehavior'];
|
|
56
|
+
}
|
|
57
|
+
interface DefineAppOptions {
|
|
58
|
+
plugins?: Array<Plugin | [Plugin, ...any[]] | AppPluginConfig>;
|
|
59
|
+
globalComponents?: Record<string, Component>;
|
|
60
|
+
provides?: Record<string | symbol, unknown>;
|
|
61
|
+
head?: PageHead;
|
|
62
|
+
rootId?: string;
|
|
63
|
+
rootAttrs?: Record<string, string>;
|
|
64
|
+
/**
|
|
65
|
+
* 应用根组件(包装组件,可选)—— 经典 Vue `App.vue` 的编程式等价物。
|
|
66
|
+
*
|
|
67
|
+
* 组件包裹在框架根组件(`UbeanAppRoot`)之上,框架出口(布局链 + 页面)
|
|
68
|
+
* 通过**默认 slot** 注入,组件内用 `<slot />` 声明渲染位置:
|
|
69
|
+
*
|
|
70
|
+
* ```vue
|
|
71
|
+
* <!-- src/app.ts 对应的 AppRoot.vue -->
|
|
72
|
+
* <template>
|
|
73
|
+
* <SConfigProvider>
|
|
74
|
+
* <AppHeader />
|
|
75
|
+
* <slot /> <!-- 布局链 + 页面在这里渲染 -->
|
|
76
|
+
* </SConfigProvider>
|
|
77
|
+
* </template>
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* 适合放置"必须在布局之上"的全局内容:全局 ConfigProvider/主题上下文、
|
|
81
|
+
* 覆盖布局自身的错误边界、全局过渡/动效容器等。不要用它渲染
|
|
82
|
+
* `<PageView />` / `<RouterView />` —— 那会绕过布局链;出口是 `<slot />`。
|
|
83
|
+
*
|
|
84
|
+
* 自动检测:`src/app.vue`(小写,Nuxt 风格,优先)/ `src/App.vue`
|
|
85
|
+
* (大写,经典 Vue 约定)文件约定(与 loading/error 特殊页同模式),
|
|
86
|
+
* 两者都存在时取小写;无该文件时忽略。优先级:
|
|
87
|
+
* `defineApp({ appRoot })` > `src/app.vue` > `src/App.vue`。
|
|
88
|
+
*/
|
|
89
|
+
appRoot?: Component;
|
|
90
|
+
/**
|
|
91
|
+
* 路由钩子配置,用于注册 vue-router 的导航守卫。
|
|
92
|
+
* 在 Client 和 SSR 都会执行。
|
|
93
|
+
*/
|
|
94
|
+
router?: RouterConfig;
|
|
95
|
+
onAppCreated?: (app: App) => void | Promise<void>;
|
|
96
|
+
onClientReady?: (app: App) => void | Promise<void>;
|
|
97
|
+
errorComponent?: Component;
|
|
98
|
+
loadingComponent?: Component;
|
|
99
|
+
viewTransitions?: boolean | ViewTransitionOptions;
|
|
100
|
+
/**
|
|
101
|
+
* SSR 专用:在 `renderToString(app)` 完成后调用,从 app 实例提取需要
|
|
102
|
+
* 序列化到客户端的状态(如 Pinia 的 `pinia.state.value`)。
|
|
103
|
+
*
|
|
104
|
+
* 返回的对象会被 `safeJsonStringify` 序列化并注入到 HTML 的
|
|
105
|
+
* `__UBEAN_STATE__` script 标签中。
|
|
106
|
+
*
|
|
107
|
+
* 仅在 server mode 下生效;client mode 下被忽略。
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { createPinia } from 'pinia';
|
|
112
|
+
* defineApp({
|
|
113
|
+
* plugins: [createPinia()],
|
|
114
|
+
* serializeState: (app) => ({
|
|
115
|
+
* pinia: app.config.globalProperties.$pinia.state.value
|
|
116
|
+
* })
|
|
117
|
+
* });
|
|
118
|
+
* ```
|
|
119
|
+
*/
|
|
120
|
+
serializeState?: (app: App) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
121
|
+
/**
|
|
122
|
+
* Client 专用:在 `applyAppConfig`(注册插件/provide)之后、`app.mount()` 之前调用,
|
|
123
|
+
* 用于从 `__UBEAN_STATE__` 反序列化的状态回填到 app(如 Pinia 的水合)。
|
|
124
|
+
*
|
|
125
|
+
* `state` 即 `serializeState` 在服务端返回的对象;若服务端未配置 `serializeState`
|
|
126
|
+
* 或返回空,`state` 为 `null`。
|
|
127
|
+
*
|
|
128
|
+
* 仅在 client mode 下生效;server mode 下被忽略。
|
|
129
|
+
*
|
|
130
|
+
* @example
|
|
131
|
+
* ```ts
|
|
132
|
+
* import { createPinia } from 'pinia';
|
|
133
|
+
* defineApp({
|
|
134
|
+
* plugins: [createPinia()],
|
|
135
|
+
* hydrateState: (app, state) => {
|
|
136
|
+
* if (state?.pinia) {
|
|
137
|
+
* app.config.globalProperties.$pinia.state.value = state.pinia;
|
|
138
|
+
* }
|
|
139
|
+
* }
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
hydrateState?: (app: App, state: Record<string, unknown> | null) => void;
|
|
144
|
+
}
|
|
145
|
+
interface ResolvedAppConfig {
|
|
146
|
+
plugins: AppPluginConfig[];
|
|
147
|
+
globalComponents: Record<string, Component>;
|
|
148
|
+
provides: Record<string | symbol, unknown>;
|
|
149
|
+
head?: PageHead;
|
|
150
|
+
rootId: string;
|
|
151
|
+
rootAttrs: Record<string, string>;
|
|
152
|
+
/**
|
|
153
|
+
* 应用根组件(包装组件,可选)。语义见 `DefineAppOptions.appRoot`。
|
|
154
|
+
*/
|
|
155
|
+
appRoot?: Component;
|
|
156
|
+
router?: RouterConfig;
|
|
157
|
+
onAppCreated?: (app: App) => void | Promise<void>;
|
|
158
|
+
onClientReady?: (app: App) => void | Promise<void>;
|
|
159
|
+
errorComponent?: Component;
|
|
160
|
+
loadingComponent?: Component;
|
|
161
|
+
viewTransitions?: boolean | ViewTransitionOptions;
|
|
162
|
+
serializeState?: (app: App) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
163
|
+
hydrateState?: (app: App, state: Record<string, unknown> | null) => void;
|
|
164
|
+
}
|
|
165
|
+
declare function defineApp(options: DefineAppOptions): ResolvedAppConfig;
|
|
166
|
+
declare function applyAppConfig(app: App, config: ResolvedAppConfig, mode: 'client' | 'server'): void;
|
|
167
|
+
declare function createDefaultAppConfig(): ResolvedAppConfig;
|
|
168
|
+
/**
|
|
169
|
+
* 从多个 `ResolvedAppConfig` 合并出一个最终配置(shared + client/server)。
|
|
170
|
+
*
|
|
171
|
+
* `serializeState` 与 `hydrateState` 的合并语义:server 配置的 `serializeState` 优先,
|
|
172
|
+
* client 配置的 `hydrateState` 优先;shared 配置作为默认值。
|
|
173
|
+
*
|
|
174
|
+
* 这个函数在 `virtual:ubean-app` 虚拟模块中以 JS 字符串形式重新实现
|
|
175
|
+
* (`_mergeAppConfig`),保持两者语义一致。
|
|
176
|
+
*/
|
|
177
|
+
declare function mergeAppConfig(base: ResolvedAppConfig, ...configs: (ResolvedAppConfig | null | undefined)[]): ResolvedAppConfig;
|
|
178
|
+
//#endregion
|
|
179
|
+
export { applyAppConfig as a, mergeAppConfig as c, RouterConfig as i, DefineAppOptions as n, createDefaultAppConfig as o, ResolvedAppConfig as r, defineApp as s, AppPluginConfig as t };
|
package/dist/define-app.d.ts
CHANGED
|
@@ -1,168 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Router } from "vue-router";
|
|
3
|
-
import { ViewTransitionOptions } from "@ubean/vue";
|
|
4
|
-
import { PageHead } from "@ubean/shared";
|
|
5
|
-
//#region src/define-app.d.ts
|
|
6
|
-
interface AppPluginConfig {
|
|
7
|
-
plugin: Plugin | [Plugin, ...any[]];
|
|
8
|
-
mode?: 'all' | 'client' | 'server';
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Router 钩子配置 — 暴露 vue-router 的导航守卫注册入口。
|
|
12
|
-
*
|
|
13
|
-
* `setup(router)` 在 router 实例创建后、`app.use(router)` 之前调用,
|
|
14
|
-
* 因此守卫能拦截首次导航(包括 SSR 的初始 URL push)。
|
|
15
|
-
*
|
|
16
|
-
* Client 和 SSR 都会执行,适合做鉴权、埋点、进度条等逻辑。
|
|
17
|
-
*
|
|
18
|
-
* @example
|
|
19
|
-
* ```ts
|
|
20
|
-
* defineApp({
|
|
21
|
-
* router: {
|
|
22
|
-
* setup(router) {
|
|
23
|
-
* router.beforeEach((to, from) => {
|
|
24
|
-
* if (to.meta.requiresAuth && !isAuthenticated()) {
|
|
25
|
-
* return '/login';
|
|
26
|
-
* }
|
|
27
|
-
* });
|
|
28
|
-
* router.afterEach((to) => {
|
|
29
|
-
* analytics.track('page_view', { path: to.fullPath });
|
|
30
|
-
* });
|
|
31
|
-
* }
|
|
32
|
-
* }
|
|
33
|
-
* });
|
|
34
|
-
* ```
|
|
35
|
-
*/
|
|
36
|
-
interface RouterConfig {
|
|
37
|
-
/**
|
|
38
|
-
* 在 router 创建后、初始导航前调用。
|
|
39
|
-
* 用于注册 `beforeEach` / `beforeResolve` / `afterEach` 等守卫。
|
|
40
|
-
*
|
|
41
|
-
* 注意:setup 必须同步注册守卫(虽然守卫本身可以返回 Promise)。
|
|
42
|
-
* 不要在 setup 中执行异步操作(如请求 API),因为这会延迟首次导航。
|
|
43
|
-
*/
|
|
44
|
-
setup?: (router: Router) => void;
|
|
45
|
-
}
|
|
46
|
-
interface DefineAppOptions {
|
|
47
|
-
plugins?: Array<Plugin | [Plugin, ...any[]] | AppPluginConfig>;
|
|
48
|
-
globalComponents?: Record<string, Component>;
|
|
49
|
-
provides?: Record<string | symbol, unknown>;
|
|
50
|
-
head?: PageHead;
|
|
51
|
-
rootId?: string;
|
|
52
|
-
rootAttrs?: Record<string, string>;
|
|
53
|
-
/**
|
|
54
|
-
* 应用根组件(包装组件,可选)—— 经典 Vue `App.vue` 的编程式等价物。
|
|
55
|
-
*
|
|
56
|
-
* 组件包裹在框架根组件(`UbeanAppRoot`)之上,框架出口(布局链 + 页面)
|
|
57
|
-
* 通过**默认 slot** 注入,组件内用 `<slot />` 声明渲染位置:
|
|
58
|
-
*
|
|
59
|
-
* ```vue
|
|
60
|
-
* <!-- src/app.ts 对应的 AppRoot.vue -->
|
|
61
|
-
* <template>
|
|
62
|
-
* <SConfigProvider>
|
|
63
|
-
* <AppHeader />
|
|
64
|
-
* <slot /> <!-- 布局链 + 页面在这里渲染 -->
|
|
65
|
-
* </SConfigProvider>
|
|
66
|
-
* </template>
|
|
67
|
-
* ```
|
|
68
|
-
*
|
|
69
|
-
* 适合放置"必须在布局之上"的全局内容:全局 ConfigProvider/主题上下文、
|
|
70
|
-
* 覆盖布局自身的错误边界、全局过渡/动效容器等。不要用它渲染
|
|
71
|
-
* `<PageView />` / `<RouterView />` —— 那会绕过布局链;出口是 `<slot />`。
|
|
72
|
-
*
|
|
73
|
-
* 自动检测:`src/app.vue`(小写,Nuxt 风格,优先)/ `src/App.vue`
|
|
74
|
-
* (大写,经典 Vue 约定)文件约定(与 loading/error 特殊页同模式),
|
|
75
|
-
* 两者都存在时取小写;无该文件时忽略。优先级:
|
|
76
|
-
* `defineApp({ appRoot })` > `src/app.vue` > `src/App.vue`。
|
|
77
|
-
*/
|
|
78
|
-
appRoot?: Component;
|
|
79
|
-
/**
|
|
80
|
-
* 路由钩子配置,用于注册 vue-router 的导航守卫。
|
|
81
|
-
* 在 Client 和 SSR 都会执行。
|
|
82
|
-
*/
|
|
83
|
-
router?: RouterConfig;
|
|
84
|
-
onAppCreated?: (app: App) => void | Promise<void>;
|
|
85
|
-
onClientReady?: (app: App) => void | Promise<void>;
|
|
86
|
-
errorComponent?: Component;
|
|
87
|
-
loadingComponent?: Component;
|
|
88
|
-
viewTransitions?: boolean | ViewTransitionOptions;
|
|
89
|
-
/**
|
|
90
|
-
* SSR 专用:在 `renderToString(app)` 完成后调用,从 app 实例提取需要
|
|
91
|
-
* 序列化到客户端的状态(如 Pinia 的 `pinia.state.value`)。
|
|
92
|
-
*
|
|
93
|
-
* 返回的对象会被 `safeJsonStringify` 序列化并注入到 HTML 的
|
|
94
|
-
* `__UBEAN_STATE__` script 标签中。
|
|
95
|
-
*
|
|
96
|
-
* 仅在 server mode 下生效;client mode 下被忽略。
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```ts
|
|
100
|
-
* import { createPinia } from 'pinia';
|
|
101
|
-
* defineApp({
|
|
102
|
-
* plugins: [createPinia()],
|
|
103
|
-
* serializeState: (app) => ({
|
|
104
|
-
* pinia: app.config.globalProperties.$pinia.state.value
|
|
105
|
-
* })
|
|
106
|
-
* });
|
|
107
|
-
* ```
|
|
108
|
-
*/
|
|
109
|
-
serializeState?: (app: App) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
110
|
-
/**
|
|
111
|
-
* Client 专用:在 `applyAppConfig`(注册插件/provide)之后、`app.mount()` 之前调用,
|
|
112
|
-
* 用于从 `__UBEAN_STATE__` 反序列化的状态回填到 app(如 Pinia 的水合)。
|
|
113
|
-
*
|
|
114
|
-
* `state` 即 `serializeState` 在服务端返回的对象;若服务端未配置 `serializeState`
|
|
115
|
-
* 或返回空,`state` 为 `null`。
|
|
116
|
-
*
|
|
117
|
-
* 仅在 client mode 下生效;server mode 下被忽略。
|
|
118
|
-
*
|
|
119
|
-
* @example
|
|
120
|
-
* ```ts
|
|
121
|
-
* import { createPinia } from 'pinia';
|
|
122
|
-
* defineApp({
|
|
123
|
-
* plugins: [createPinia()],
|
|
124
|
-
* hydrateState: (app, state) => {
|
|
125
|
-
* if (state?.pinia) {
|
|
126
|
-
* app.config.globalProperties.$pinia.state.value = state.pinia;
|
|
127
|
-
* }
|
|
128
|
-
* }
|
|
129
|
-
* });
|
|
130
|
-
* ```
|
|
131
|
-
*/
|
|
132
|
-
hydrateState?: (app: App, state: Record<string, unknown> | null) => void;
|
|
133
|
-
}
|
|
134
|
-
interface ResolvedAppConfig {
|
|
135
|
-
plugins: AppPluginConfig[];
|
|
136
|
-
globalComponents: Record<string, Component>;
|
|
137
|
-
provides: Record<string | symbol, unknown>;
|
|
138
|
-
head?: PageHead;
|
|
139
|
-
rootId: string;
|
|
140
|
-
rootAttrs: Record<string, string>;
|
|
141
|
-
/**
|
|
142
|
-
* 应用根组件(包装组件,可选)。语义见 `DefineAppOptions.appRoot`。
|
|
143
|
-
*/
|
|
144
|
-
appRoot?: Component;
|
|
145
|
-
router?: RouterConfig;
|
|
146
|
-
onAppCreated?: (app: App) => void | Promise<void>;
|
|
147
|
-
onClientReady?: (app: App) => void | Promise<void>;
|
|
148
|
-
errorComponent?: Component;
|
|
149
|
-
loadingComponent?: Component;
|
|
150
|
-
viewTransitions?: boolean | ViewTransitionOptions;
|
|
151
|
-
serializeState?: (app: App) => Record<string, unknown> | Promise<Record<string, unknown>>;
|
|
152
|
-
hydrateState?: (app: App, state: Record<string, unknown> | null) => void;
|
|
153
|
-
}
|
|
154
|
-
declare function defineApp(options: DefineAppOptions): ResolvedAppConfig;
|
|
155
|
-
declare function applyAppConfig(app: App, config: ResolvedAppConfig, mode: 'client' | 'server'): void;
|
|
156
|
-
declare function createDefaultAppConfig(): ResolvedAppConfig;
|
|
157
|
-
/**
|
|
158
|
-
* 从多个 `ResolvedAppConfig` 合并出一个最终配置(shared + client/server)。
|
|
159
|
-
*
|
|
160
|
-
* `serializeState` 与 `hydrateState` 的合并语义:server 配置的 `serializeState` 优先,
|
|
161
|
-
* client 配置的 `hydrateState` 优先;shared 配置作为默认值。
|
|
162
|
-
*
|
|
163
|
-
* 这个函数在 `virtual:ubean-app` 虚拟模块中以 JS 字符串形式重新实现
|
|
164
|
-
* (`_mergeAppConfig`),保持两者语义一致。
|
|
165
|
-
*/
|
|
166
|
-
declare function mergeAppConfig(base: ResolvedAppConfig, ...configs: (ResolvedAppConfig | null | undefined)[]): ResolvedAppConfig;
|
|
167
|
-
//#endregion
|
|
1
|
+
import { a as applyAppConfig, c as mergeAppConfig, i as RouterConfig, n as DefineAppOptions, o as createDefaultAppConfig, r as ResolvedAppConfig, s as defineApp, t as AppPluginConfig } from "./define-app-RzHOZlYB.js";
|
|
168
2
|
export { AppPluginConfig, DefineAppOptions, ResolvedAppConfig, RouterConfig, applyAppConfig, createDefaultAppConfig, defineApp, mergeAppConfig };
|
package/dist/define-app.js
CHANGED
|
@@ -84,13 +84,17 @@ function mergeAppConfig(base, ...configs) {
|
|
|
84
84
|
if (cfg.viewTransitions !== void 0) result.viewTransitions = cfg.viewTransitions;
|
|
85
85
|
if (cfg.serializeState) result.serializeState = cfg.serializeState;
|
|
86
86
|
if (cfg.hydrateState) result.hydrateState = cfg.hydrateState;
|
|
87
|
-
if (cfg.router
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
|
|
87
|
+
if (cfg.router) {
|
|
88
|
+
const prev = result.router;
|
|
89
|
+
const setup = cfg.router.setup ? prev?.setup ? (router) => {
|
|
90
|
+
prev.setup(router);
|
|
91
91
|
cfg.router.setup(router);
|
|
92
|
-
}
|
|
93
|
-
|
|
92
|
+
} : cfg.router.setup : prev?.setup;
|
|
93
|
+
const scrollBehavior = cfg.router.scrollBehavior !== void 0 ? cfg.router.scrollBehavior : prev?.scrollBehavior;
|
|
94
|
+
result.router = {
|
|
95
|
+
setup,
|
|
96
|
+
...scrollBehavior !== void 0 ? { scrollBehavior } : {}
|
|
97
|
+
};
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
return result;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, T as definePage, _ as createUbeanClientApp, b as useSeoMeta, h as UbeanAppOptions, k as createUbeanRouter, m as UbeanAppInstance, n as Head, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead } from "./app-
|
|
2
|
-
import {
|
|
1
|
+
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, T as definePage, _ as createUbeanClientApp, b as useSeoMeta, h as UbeanAppOptions, k as createUbeanRouter, m as UbeanAppInstance, n as Head, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead } from "./app-emLZM9XN.js";
|
|
2
|
+
import { a as applyAppConfig, c as mergeAppConfig, n as DefineAppOptions, o as createDefaultAppConfig, r as ResolvedAppConfig, s as defineApp, t as AppPluginConfig } from "./define-app-RzHOZlYB.js";
|
|
3
3
|
import { App, ComputedRef, Ref, ShallowRef } from "vue";
|
|
4
4
|
import "vue-router";
|
|
5
5
|
import { ERROR_KEY, ErrorBoundary, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, LayoutChainContext, LayoutChainRenderer, Link, PAGE_KEY, PageView, RouteLocation, RouteLocationRaw, SSR_KEY, SlotView, TRANSITION_KEY, TypedLinkProps, UbeanVueOptions, UbeanVuePageData, UseCacheViewsReturn, UsePageTransitionReturn, UseReloadSignalReturn, ViewTransitionOptions, clearPageTransition, disablePageCache, enablePageCache, excludePageCache, getCacheEnabled, getCachedViewNames, getExcludedViewNames, getNamedPageWrapper, getNavigationType, getPageTransitionName, getReloadCounter, includePageCache, initCachedViewsFromRoutes, invalidatePageCache, isActiveRoute, isCacheEnabled, isPageCached, isPageExcluded, isReloading, reloadPage, resetNamedPageWrappers, resetRouteCache, resolveRoute, setPageTransition, supportsViewTransitions, ubeanVue, useCacheViews, usePageTransition, useReloadSignal, useViewTransition, useViewTransitionState, withViewTransition } from "@ubean/vue";
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, b as defineMiddleware, g as useSeoMeta, m as createUbeanSSRApp, n as Head, p as createUbeanClientApp, x as definePage, y as defineMeta } from "./app-
|
|
1
|
+
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, b as defineMiddleware, g as useSeoMeta, m as createUbeanSSRApp, n as Head, p as createUbeanClientApp, x as definePage, y as defineMeta } from "./app-Bt-2meGm.js";
|
|
2
2
|
import { a as getI18nRuntimeConfig, c as installUbeanI18n, d as switchLocalePath, f as useLocaleHead, h as useSwitchLocalePath, i as extractLocaleFromPath, l as localizePath, m as useLocaleRoute, n as configureI18nRuntime, o as getLocale, p as useLocalePath, r as createUbeanI18n, s as initClientI18n, u as setLocale } from "./i18n-CAeXKTpy.js";
|
|
3
3
|
import { applyAppConfig, createDefaultAppConfig, defineApp, mergeAppConfig } from "./define-app.js";
|
|
4
4
|
import { computed, getCurrentInstance, markRaw, onMounted, onScopeDispose, onUnmounted, ref, shallowRef, watch } from "vue";
|
package/dist/server.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, S as useViewTransition, T as definePage, _ as createUbeanClientApp, a as LOCALIZE_PATH_KEY, b as useSeoMeta, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, k as createUbeanRouter, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead, y as ubeanVue } from "./app-
|
|
1
|
+
import { C as defineMeta, D as usePage, E as UbeanVuePage, O as CreateUbeanRouterOptions, S as useViewTransition, T as definePage, _ as createUbeanClientApp, a as LOCALIZE_PATH_KEY, b as useSeoMeta, c as Link, d as SSR_KEY, f as SlotView, g as UbeanVueOptions, h as UbeanAppOptions, i as LOADING_KEY, k as createUbeanRouter, l as PAGE_KEY, m as UbeanAppInstance, n as Head, o as LayoutChainContext, p as TRANSITION_KEY, r as LAYOUT_CHAIN_KEY, s as LayoutChainRenderer, t as ERROR_KEY, u as PageView, v as createUbeanSSRApp, w as defineMiddleware, x as useUnheadHead, y as ubeanVue } from "./app-emLZM9XN.js";
|
|
2
2
|
import { createHead as createServerHead } from "@unhead/vue/server";
|
|
3
3
|
export { type CreateUbeanRouterOptions, ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, type LayoutChainContext, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, UbeanAppInstance, UbeanAppOptions, type UbeanVueOptions, type UbeanVuePage, createServerHead, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useSeoMeta, useViewTransition };
|
package/dist/server.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, a as LOCALIZE_PATH_KEY, b as defineMiddleware, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useSeoMeta, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useViewTransition, x as definePage, y as defineMeta } from "./app-
|
|
1
|
+
import { C as usePage, S as createUbeanRouter, _ as useUnheadHead, a as LOCALIZE_PATH_KEY, b as defineMiddleware, c as PAGE_KEY, d as SlotView, f as TRANSITION_KEY, g as useSeoMeta, h as ubeanVue, i as LOADING_KEY, l as PageView, m as createUbeanSSRApp, n as Head, o as LayoutChainRenderer, p as createUbeanClientApp, r as LAYOUT_CHAIN_KEY, s as Link, t as ERROR_KEY, u as SSR_KEY, v as useViewTransition, x as definePage, y as defineMeta } from "./app-Bt-2meGm.js";
|
|
2
2
|
import { createHead as createServerHead } from "@unhead/vue/server";
|
|
3
3
|
export { ERROR_KEY, Head, LAYOUT_CHAIN_KEY, LOADING_KEY, LOCALIZE_PATH_KEY, LayoutChainRenderer, Link, PAGE_KEY, PageView, SSR_KEY, SlotView, TRANSITION_KEY, createServerHead, createUbeanClientApp, createUbeanRouter, createUbeanSSRApp, defineMeta, defineMiddleware, definePage, ubeanVue, useUnheadHead as useHead, usePage, useSeoMeta, useViewTransition };
|
package/dist/ssr.d.ts
CHANGED
package/dist/ssr.js
CHANGED
|
@@ -124,6 +124,7 @@ async function prepareRender(options, pageObj, renderContext) {
|
|
|
124
124
|
defaultLayout: options.defaultLayout,
|
|
125
125
|
head,
|
|
126
126
|
i18n,
|
|
127
|
+
router: appConfig?.router,
|
|
127
128
|
appRoot: appConfig?.appRoot
|
|
128
129
|
});
|
|
129
130
|
if (appConfig) await applyServerAppConfig(createdApp, appConfig);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ubean/client",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.5",
|
|
4
4
|
"description": "Framework client runtime for ubean — layered over the lean @ubean/vue kernel, adding app factories, unhead, i18n, data layer, islands hydration and SSR state helpers",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
}
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@ubean/i18n": "0.4.
|
|
36
|
-
"@ubean/islands": "0.4.
|
|
37
|
-
"@ubean/pages": "0.4.
|
|
38
|
-
"@ubean/shared": "0.4.
|
|
39
|
-
"@ubean/vue": "0.4.
|
|
35
|
+
"@ubean/i18n": "0.4.5",
|
|
36
|
+
"@ubean/islands": "0.4.5",
|
|
37
|
+
"@ubean/pages": "0.4.5",
|
|
38
|
+
"@ubean/shared": "0.4.5",
|
|
39
|
+
"@ubean/vue": "0.4.5",
|
|
40
40
|
"@unhead/vue": "^3.4.0",
|
|
41
41
|
"@vue/server-renderer": "^3.5.42",
|
|
42
42
|
"vue": "^3.5.42",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"vite-plus": "0.3.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
|
-
"@ubean/seo": "0.4.
|
|
52
|
+
"@ubean/seo": "0.4.5"
|
|
53
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|
|
55
55
|
"@ubean/seo": {
|