@esmx/router-vue 3.0.0-rc.69 → 3.0.0-rc.71
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/README.md +13 -6
- package/README.zh-CN.md +12 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +1 -0
- package/dist/index.test.mjs +30 -20
- package/dist/plugin.mjs +3 -0
- package/dist/plugin.test.mjs +3 -3
- package/dist/router-link.test.mjs +1 -1
- package/dist/router-view.test.mjs +6 -6
- package/dist/use.d.ts +9 -0
- package/dist/use.mjs +29 -13
- package/dist/use.test.mjs +220 -3
- package/package.json +7 -7
- package/src/index.test.ts +32 -22
- package/src/index.ts +1 -0
- package/src/plugin.test.ts +3 -3
- package/src/plugin.ts +4 -0
- package/src/router-link.test.ts +1 -1
- package/src/router-view.test.ts +6 -6
- package/src/use.test.ts +265 -3
- package/src/use.ts +39 -20
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
## Features
|
|
32
|
+
## 🚀 Features
|
|
33
33
|
|
|
34
34
|
✨ **Universal Vue Support** - Works with both Vue 2.7+ and Vue 3
|
|
35
35
|
🎯 **Composition API First** - Built for modern Vue development
|
|
@@ -38,13 +38,20 @@
|
|
|
38
38
|
⚡ **High Performance** - Optimized for production use
|
|
39
39
|
🔄 **SSR Compatible** - Server-side rendering support
|
|
40
40
|
|
|
41
|
-
## Installation
|
|
41
|
+
## 📦 Installation
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
+
# npm
|
|
44
45
|
npm install @esmx/router @esmx/router-vue
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add @esmx/router @esmx/router-vue
|
|
49
|
+
|
|
50
|
+
# yarn
|
|
51
|
+
yarn add @esmx/router @esmx/router-vue
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
## Quick Start
|
|
54
|
+
## 🚀 Quick Start
|
|
48
55
|
|
|
49
56
|
### Vue 3
|
|
50
57
|
|
|
@@ -189,7 +196,7 @@ export default defineComponent({
|
|
|
189
196
|
</script>
|
|
190
197
|
```
|
|
191
198
|
|
|
192
|
-
## API Reference
|
|
199
|
+
## 📚 API Reference
|
|
193
200
|
|
|
194
201
|
### Components
|
|
195
202
|
|
|
@@ -553,11 +560,11 @@ app.use(RouterPlugin);
|
|
|
553
560
|
|
|
554
561
|
We welcome contributions! Please feel free to submit issues and pull requests.
|
|
555
562
|
|
|
556
|
-
## License
|
|
563
|
+
## 📄 License
|
|
557
564
|
|
|
558
565
|
MIT © [Esmx Team](https://github.com/esmnext/esmx)
|
|
559
566
|
|
|
560
567
|
## Related Packages
|
|
561
568
|
|
|
562
569
|
- [@esmx/router](https://github.com/esmnext/esmx/tree/master/packages/router) - Core router package
|
|
563
|
-
- [@esmx/core](https://github.com/esmnext/esmx/tree/master/packages/core) - Esmx core framework
|
|
570
|
+
- [@esmx/core](https://github.com/esmnext/esmx/tree/master/packages/core) - Esmx core framework
|
package/README.zh-CN.md
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
## 特性
|
|
32
|
+
## 🚀 特性
|
|
33
33
|
|
|
34
34
|
✨ **通用 Vue 支持** - 同时支持 Vue 2.7+ 和 Vue 3
|
|
35
35
|
🎯 **组合式 API 优先** - 为现代 Vue 开发而构建
|
|
@@ -38,13 +38,20 @@
|
|
|
38
38
|
⚡ **高性能** - 为生产环境优化
|
|
39
39
|
🔄 **SSR 兼容** - 支持服务端渲染
|
|
40
40
|
|
|
41
|
-
## 安装
|
|
41
|
+
## 📦 安装
|
|
42
42
|
|
|
43
43
|
```bash
|
|
44
|
+
# npm
|
|
44
45
|
npm install @esmx/router @esmx/router-vue
|
|
46
|
+
|
|
47
|
+
# pnpm
|
|
48
|
+
pnpm add @esmx/router @esmx/router-vue
|
|
49
|
+
|
|
50
|
+
# yarn
|
|
51
|
+
yarn add @esmx/router @esmx/router-vue
|
|
45
52
|
```
|
|
46
53
|
|
|
47
|
-
## 快速开始
|
|
54
|
+
## 🚀 快速开始
|
|
48
55
|
|
|
49
56
|
### Vue 3
|
|
50
57
|
|
|
@@ -189,7 +196,7 @@ export default defineComponent({
|
|
|
189
196
|
</script>
|
|
190
197
|
```
|
|
191
198
|
|
|
192
|
-
## API 参考
|
|
199
|
+
## 📚 API 参考
|
|
193
200
|
|
|
194
201
|
### 组件
|
|
195
202
|
|
|
@@ -553,7 +560,7 @@ app.use(RouterPlugin);
|
|
|
553
560
|
|
|
554
561
|
我们欢迎贡献!请随时提交 issues 和 pull requests。
|
|
555
562
|
|
|
556
|
-
## 许可证
|
|
563
|
+
## 📄 许可证
|
|
557
564
|
|
|
558
565
|
MIT © [Esmx 团队](https://github.com/esmnext/esmx)
|
|
559
566
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type * from './vue2';
|
|
2
2
|
export type * from './vue3';
|
|
3
|
-
export { useRouter, useRoute, useProvideRouter, useLink, useRouterViewDepth, getRoute, getRouter } from './use';
|
|
3
|
+
export { useRouter, useRoute, useProvideRouter, useLink, useRouterViewDepth, getRouterViewDepth, getRoute, getRouter } from './use';
|
|
4
4
|
export { RouterLink } from './router-link';
|
|
5
5
|
export { RouterView } from './router-view';
|
|
6
6
|
export { RouterPlugin } from './plugin';
|
package/dist/index.mjs
CHANGED
package/dist/index.test.mjs
CHANGED
|
@@ -18,6 +18,14 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
18
18
|
expect(RouterVueModule.useLink).toBeDefined();
|
|
19
19
|
expect(typeof RouterVueModule.useLink).toBe("function");
|
|
20
20
|
});
|
|
21
|
+
it("should export useRouterViewDepth function", () => {
|
|
22
|
+
expect(RouterVueModule.useRouterViewDepth).toBeDefined();
|
|
23
|
+
expect(typeof RouterVueModule.useRouterViewDepth).toBe("function");
|
|
24
|
+
});
|
|
25
|
+
it("should export getRouterViewDepth function", () => {
|
|
26
|
+
expect(RouterVueModule.getRouterViewDepth).toBeDefined();
|
|
27
|
+
expect(typeof RouterVueModule.getRouterViewDepth).toBe("function");
|
|
28
|
+
});
|
|
21
29
|
});
|
|
22
30
|
describe("Options API Exports", () => {
|
|
23
31
|
it("should export getRouter function", () => {
|
|
@@ -61,6 +69,7 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
61
69
|
"useProvideRouter",
|
|
62
70
|
"useLink",
|
|
63
71
|
"useRouterViewDepth",
|
|
72
|
+
"getRouterViewDepth",
|
|
64
73
|
// Options API
|
|
65
74
|
"getRouter",
|
|
66
75
|
"getRoute",
|
|
@@ -85,6 +94,7 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
85
94
|
"useProvideRouter",
|
|
86
95
|
"useLink",
|
|
87
96
|
"useRouterViewDepth",
|
|
97
|
+
"getRouterViewDepth",
|
|
88
98
|
"getRouter",
|
|
89
99
|
"getRoute",
|
|
90
100
|
"RouterLink",
|
|
@@ -101,37 +111,35 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
101
111
|
it("should have correct function signatures for Composition API", () => {
|
|
102
112
|
expect(() => {
|
|
103
113
|
RouterVueModule.useRouter();
|
|
104
|
-
}).toThrow(
|
|
114
|
+
}).toThrow(
|
|
115
|
+
"[@esmx/router-vue] Must be used within setup() or other composition functions"
|
|
116
|
+
);
|
|
105
117
|
expect(() => {
|
|
106
118
|
RouterVueModule.useRoute();
|
|
107
|
-
}).toThrow(
|
|
119
|
+
}).toThrow(
|
|
120
|
+
"[@esmx/router-vue] Must be used within setup() or other composition functions"
|
|
121
|
+
);
|
|
108
122
|
expect(() => {
|
|
109
123
|
RouterVueModule.useLink({
|
|
110
124
|
to: "/test",
|
|
111
125
|
type: "push",
|
|
112
126
|
exact: "include"
|
|
113
127
|
});
|
|
114
|
-
}).toThrow(
|
|
128
|
+
}).toThrow(
|
|
129
|
+
"[@esmx/router-vue] Must be used within setup() or other composition functions"
|
|
130
|
+
);
|
|
115
131
|
});
|
|
116
132
|
it("should have correct function signatures for Options API", () => {
|
|
117
133
|
expect(() => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
"Router context not found"
|
|
123
|
-
);
|
|
124
|
-
}
|
|
125
|
-
}).not.toThrow();
|
|
134
|
+
RouterVueModule.getRouter({});
|
|
135
|
+
}).toThrow(
|
|
136
|
+
"[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component."
|
|
137
|
+
);
|
|
126
138
|
expect(() => {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
"Router context not found"
|
|
132
|
-
);
|
|
133
|
-
}
|
|
134
|
-
}).not.toThrow();
|
|
139
|
+
RouterVueModule.getRoute({});
|
|
140
|
+
}).toThrow(
|
|
141
|
+
"[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component."
|
|
142
|
+
);
|
|
135
143
|
});
|
|
136
144
|
});
|
|
137
145
|
describe("Component Properties", () => {
|
|
@@ -161,7 +169,7 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
161
169
|
expect(typeof RouterPlugin.install).toBe("function");
|
|
162
170
|
expect(() => {
|
|
163
171
|
RouterPlugin.install(null);
|
|
164
|
-
}).toThrow();
|
|
172
|
+
}).toThrow("[@esmx/router-vue] Invalid Vue app instance");
|
|
165
173
|
});
|
|
166
174
|
});
|
|
167
175
|
describe("Module Structure", () => {
|
|
@@ -176,6 +184,8 @@ describe("index.ts - Package Entry Point", () => {
|
|
|
176
184
|
"useRoute",
|
|
177
185
|
"useProvideRouter",
|
|
178
186
|
"useLink",
|
|
187
|
+
"useRouterViewDepth",
|
|
188
|
+
"getRouterViewDepth",
|
|
179
189
|
"getRouter",
|
|
180
190
|
"getRoute"
|
|
181
191
|
];
|
package/dist/plugin.mjs
CHANGED
|
@@ -9,6 +9,9 @@ export const RouterPlugin = {
|
|
|
9
9
|
*/
|
|
10
10
|
install(app) {
|
|
11
11
|
var _a;
|
|
12
|
+
if (!app) {
|
|
13
|
+
throw new Error("[@esmx/router-vue] Invalid Vue app instance");
|
|
14
|
+
}
|
|
12
15
|
const vueApp = app;
|
|
13
16
|
const target = ((_a = vueApp.config) == null ? void 0 : _a.globalProperties) || vueApp.prototype;
|
|
14
17
|
if (!target) {
|
package/dist/plugin.test.mjs
CHANGED
|
@@ -34,7 +34,7 @@ describe("plugin.ts - RouterPlugin", () => {
|
|
|
34
34
|
router = new Router({
|
|
35
35
|
mode: RouterMode.memory,
|
|
36
36
|
routes,
|
|
37
|
-
base: new URL("http://localhost:
|
|
37
|
+
base: new URL("http://localhost:8000/")
|
|
38
38
|
});
|
|
39
39
|
await router.replace("/");
|
|
40
40
|
await nextTick();
|
|
@@ -71,12 +71,12 @@ describe("plugin.ts - RouterPlugin", () => {
|
|
|
71
71
|
it("should throw error for null app instance", () => {
|
|
72
72
|
expect(() => {
|
|
73
73
|
RouterPlugin.install(null);
|
|
74
|
-
}).toThrow();
|
|
74
|
+
}).toThrow("[@esmx/router-vue] Invalid Vue app instance");
|
|
75
75
|
});
|
|
76
76
|
it("should throw error for undefined app instance", () => {
|
|
77
77
|
expect(() => {
|
|
78
78
|
RouterPlugin.install(void 0);
|
|
79
|
-
}).toThrow();
|
|
79
|
+
}).toThrow("[@esmx/router-vue] Invalid Vue app instance");
|
|
80
80
|
});
|
|
81
81
|
});
|
|
82
82
|
describe("Global Properties Injection", () => {
|
|
@@ -41,7 +41,7 @@ describe("router-link.ts - RouterLink Component", () => {
|
|
|
41
41
|
root: "#test-app",
|
|
42
42
|
routes,
|
|
43
43
|
mode: RouterMode.memory,
|
|
44
|
-
base: new URL("http://localhost:
|
|
44
|
+
base: new URL("http://localhost:8000/")
|
|
45
45
|
});
|
|
46
46
|
await router.replace("/");
|
|
47
47
|
await nextTick();
|
|
@@ -63,7 +63,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
63
63
|
root: "#test-app",
|
|
64
64
|
routes,
|
|
65
65
|
mode: RouterMode.memory,
|
|
66
|
-
base: new URL("http://localhost:
|
|
66
|
+
base: new URL("http://localhost:8000/")
|
|
67
67
|
});
|
|
68
68
|
await router.replace("/");
|
|
69
69
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -149,7 +149,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
149
149
|
root: "#test-app",
|
|
150
150
|
routes,
|
|
151
151
|
mode: RouterMode.memory,
|
|
152
|
-
base: new URL("http://localhost:
|
|
152
|
+
base: new URL("http://localhost:8000/")
|
|
153
153
|
});
|
|
154
154
|
await functionRouter.replace("/function");
|
|
155
155
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -251,7 +251,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
251
251
|
root: "#test-app",
|
|
252
252
|
routes: nestedRoutes,
|
|
253
253
|
mode: RouterMode.memory,
|
|
254
|
-
base: new URL("http://localhost:
|
|
254
|
+
base: new URL("http://localhost:8000/")
|
|
255
255
|
});
|
|
256
256
|
await nestedRouter.replace("/level1/level2");
|
|
257
257
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -313,7 +313,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
313
313
|
root: "#test-app",
|
|
314
314
|
routes: routesWithNull,
|
|
315
315
|
mode: RouterMode.memory,
|
|
316
|
-
base: new URL("http://localhost:
|
|
316
|
+
base: new URL("http://localhost:8000/")
|
|
317
317
|
});
|
|
318
318
|
await nullRouter.replace("/null-component");
|
|
319
319
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -346,7 +346,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
346
346
|
}
|
|
347
347
|
],
|
|
348
348
|
mode: RouterMode.memory,
|
|
349
|
-
base: new URL("http://localhost:
|
|
349
|
+
base: new URL("http://localhost:8000/")
|
|
350
350
|
});
|
|
351
351
|
await nonExistentRouter.replace("/");
|
|
352
352
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
@@ -385,7 +385,7 @@ describe("router-view.ts - RouterView Component", () => {
|
|
|
385
385
|
root: "#test-app",
|
|
386
386
|
routes: malformedRoutes,
|
|
387
387
|
mode: RouterMode.memory,
|
|
388
|
-
base: new URL("http://localhost:
|
|
388
|
+
base: new URL("http://localhost:8000/")
|
|
389
389
|
});
|
|
390
390
|
await malformedRouter.replace("/malformed");
|
|
391
391
|
await new Promise((resolve) => setTimeout(resolve, 10));
|
package/dist/use.d.ts
CHANGED
|
@@ -224,6 +224,15 @@ export declare function _useRouterViewDepth(isRender?: boolean): number;
|
|
|
224
224
|
* ```
|
|
225
225
|
*/
|
|
226
226
|
export declare function useRouterViewDepth(): number;
|
|
227
|
+
/**
|
|
228
|
+
* Get injected RouterView depth from a Vue instance's ancestors.
|
|
229
|
+
* Traverses parent chain to find the value provided under ROUTER_VIEW_DEPTH_KEY.
|
|
230
|
+
*
|
|
231
|
+
* @param instance - Vue component instance to start from
|
|
232
|
+
* @returns Injected RouterView depth value from nearest ancestor
|
|
233
|
+
* @throws {Error} If no ancestor provided ROUTER_VIEW_DEPTH_KEY
|
|
234
|
+
*/
|
|
235
|
+
export declare function getRouterViewDepth(instance: VueInstance): number;
|
|
227
236
|
/**
|
|
228
237
|
* Create reactive link helpers for navigation elements.
|
|
229
238
|
* Returns computed properties for link attributes, classes, and event handlers.
|
package/dist/use.mjs
CHANGED
|
@@ -10,21 +10,22 @@ import { createDependentProxy, createSymbolProperty } from "./util.mjs";
|
|
|
10
10
|
const ROUTER_CONTEXT_KEY = Symbol("router-context");
|
|
11
11
|
const ROUTER_INJECT_KEY = Symbol("router-inject");
|
|
12
12
|
const ROUTER_VIEW_DEPTH_KEY = Symbol("router-view-depth");
|
|
13
|
-
const ERROR_MESSAGES = {
|
|
14
|
-
SETUP_ONLY: (fnName) => "[@esmx/router-vue] ".concat(fnName, "() can only be called during setup()"),
|
|
15
|
-
CONTEXT_NOT_FOUND: "[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component."
|
|
16
|
-
};
|
|
17
13
|
const routerContextProperty = createSymbolProperty(ROUTER_CONTEXT_KEY);
|
|
18
|
-
|
|
14
|
+
const routerViewDepthProperty = createSymbolProperty(
|
|
15
|
+
ROUTER_VIEW_DEPTH_KEY
|
|
16
|
+
);
|
|
17
|
+
function getCurrentProxy() {
|
|
19
18
|
const instance = getCurrentInstance();
|
|
20
19
|
if (!instance || !instance.proxy) {
|
|
21
|
-
throw new Error(
|
|
20
|
+
throw new Error(
|
|
21
|
+
"[@esmx/router-vue] Must be used within setup() or other composition functions"
|
|
22
|
+
);
|
|
22
23
|
}
|
|
23
24
|
return instance.proxy;
|
|
24
25
|
}
|
|
25
26
|
function findRouterContext(vm) {
|
|
26
27
|
if (!vm) {
|
|
27
|
-
vm = getCurrentProxy(
|
|
28
|
+
vm = getCurrentProxy();
|
|
28
29
|
}
|
|
29
30
|
let context = routerContextProperty.get(vm);
|
|
30
31
|
if (context) {
|
|
@@ -39,7 +40,9 @@ function findRouterContext(vm) {
|
|
|
39
40
|
}
|
|
40
41
|
current = current.$parent;
|
|
41
42
|
}
|
|
42
|
-
throw new Error(
|
|
43
|
+
throw new Error(
|
|
44
|
+
"[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component."
|
|
45
|
+
);
|
|
43
46
|
}
|
|
44
47
|
export function getRouter(instance) {
|
|
45
48
|
return findRouterContext(instance).router;
|
|
@@ -47,22 +50,22 @@ export function getRouter(instance) {
|
|
|
47
50
|
export function getRoute(instance) {
|
|
48
51
|
return findRouterContext(instance).route;
|
|
49
52
|
}
|
|
50
|
-
function useRouterContext(
|
|
53
|
+
function useRouterContext() {
|
|
51
54
|
const injectedContext = inject(ROUTER_INJECT_KEY);
|
|
52
55
|
if (injectedContext) {
|
|
53
56
|
return injectedContext;
|
|
54
57
|
}
|
|
55
|
-
const proxy = getCurrentProxy(
|
|
58
|
+
const proxy = getCurrentProxy();
|
|
56
59
|
return findRouterContext(proxy);
|
|
57
60
|
}
|
|
58
61
|
export function useRouter() {
|
|
59
|
-
return useRouterContext(
|
|
62
|
+
return useRouterContext().router;
|
|
60
63
|
}
|
|
61
64
|
export function useRoute() {
|
|
62
|
-
return useRouterContext(
|
|
65
|
+
return useRouterContext().route;
|
|
63
66
|
}
|
|
64
67
|
export function useProvideRouter(router) {
|
|
65
|
-
const proxy = getCurrentProxy(
|
|
68
|
+
const proxy = getCurrentProxy();
|
|
66
69
|
const dep = ref(0);
|
|
67
70
|
const proxiedRouter = createDependentProxy(router, dep);
|
|
68
71
|
const proxiedRoute = createDependentProxy(router.route, dep);
|
|
@@ -84,12 +87,25 @@ export function _useRouterViewDepth(isRender) {
|
|
|
84
87
|
const depth = inject(ROUTER_VIEW_DEPTH_KEY, 0);
|
|
85
88
|
if (isRender) {
|
|
86
89
|
provide(ROUTER_VIEW_DEPTH_KEY, depth + 1);
|
|
90
|
+
const proxy = getCurrentProxy();
|
|
91
|
+
routerViewDepthProperty.set(proxy, depth + 1);
|
|
87
92
|
}
|
|
88
93
|
return depth;
|
|
89
94
|
}
|
|
90
95
|
export function useRouterViewDepth() {
|
|
91
96
|
return _useRouterViewDepth();
|
|
92
97
|
}
|
|
98
|
+
export function getRouterViewDepth(instance) {
|
|
99
|
+
let current = instance.$parent;
|
|
100
|
+
while (current) {
|
|
101
|
+
const value = routerViewDepthProperty.get(current);
|
|
102
|
+
if (typeof value === "number") return value;
|
|
103
|
+
current = current.$parent;
|
|
104
|
+
}
|
|
105
|
+
throw new Error(
|
|
106
|
+
"[@esmx/router-vue] RouterView depth not found. Please ensure a RouterView exists in ancestor components."
|
|
107
|
+
);
|
|
108
|
+
}
|
|
93
109
|
export function useLink(props) {
|
|
94
110
|
const router = useRouter();
|
|
95
111
|
return computed(() => {
|
package/dist/use.test.mjs
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { Router, RouterMode } from "@esmx/router";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
3
3
|
import { nextTick } from "vue";
|
|
4
|
-
import { createApp, h } from "vue";
|
|
5
|
-
import {
|
|
4
|
+
import { createApp, defineComponent, getCurrentInstance, h } from "vue";
|
|
5
|
+
import { RouterView } from "./router-view.mjs";
|
|
6
|
+
import {
|
|
7
|
+
getRouterViewDepth,
|
|
8
|
+
useProvideRouter,
|
|
9
|
+
useRoute,
|
|
10
|
+
useRouter,
|
|
11
|
+
useRouterViewDepth
|
|
12
|
+
} from "./use.mjs";
|
|
6
13
|
describe("Router Vue Integration", () => {
|
|
7
14
|
let app;
|
|
8
15
|
let router;
|
|
@@ -16,7 +23,7 @@ describe("Router Vue Integration", () => {
|
|
|
16
23
|
{ path: "/user/:id", component: {} },
|
|
17
24
|
{ path: "/new-path", component: {} }
|
|
18
25
|
],
|
|
19
|
-
base: new URL("http://localhost:
|
|
26
|
+
base: new URL("http://localhost:8000/")
|
|
20
27
|
});
|
|
21
28
|
await router.replace("/initial");
|
|
22
29
|
mountPoint = document.createElement("div");
|
|
@@ -156,4 +163,214 @@ describe("Router Vue Integration", () => {
|
|
|
156
163
|
expect(childRoute == null ? void 0 : childRoute.path).toBe("/new-path");
|
|
157
164
|
});
|
|
158
165
|
});
|
|
166
|
+
describe("RouterView Depth", () => {
|
|
167
|
+
it("should get depth in single RouterView", async () => {
|
|
168
|
+
let observedDepth;
|
|
169
|
+
const LeafProbe = defineComponent({
|
|
170
|
+
setup() {
|
|
171
|
+
const p = getCurrentInstance().proxy;
|
|
172
|
+
observedDepth = getRouterViewDepth(p);
|
|
173
|
+
return () => h("div");
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
const Level1 = defineComponent({
|
|
177
|
+
setup() {
|
|
178
|
+
return () => h("div", [h(LeafProbe)]);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
router = new Router({
|
|
182
|
+
mode: RouterMode.memory,
|
|
183
|
+
routes: [{ path: "/level1", component: Level1 }],
|
|
184
|
+
base: new URL("http://localhost:8000/")
|
|
185
|
+
});
|
|
186
|
+
await router.replace("/level1");
|
|
187
|
+
const TestApp = defineComponent({
|
|
188
|
+
setup() {
|
|
189
|
+
useProvideRouter(router);
|
|
190
|
+
return () => h("div", [h(RouterView)]);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
app = createApp(TestApp);
|
|
194
|
+
app.mount("#app");
|
|
195
|
+
await nextTick();
|
|
196
|
+
expect(observedDepth).toBe(1);
|
|
197
|
+
});
|
|
198
|
+
it("should get depth in nested RouterView", async () => {
|
|
199
|
+
let observedDepth;
|
|
200
|
+
const LeafProbe = defineComponent({
|
|
201
|
+
setup() {
|
|
202
|
+
const p = getCurrentInstance().proxy;
|
|
203
|
+
observedDepth = getRouterViewDepth(p);
|
|
204
|
+
return () => h("div");
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
const Level1 = defineComponent({
|
|
208
|
+
setup() {
|
|
209
|
+
return () => h("div", [h(RouterView)]);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
const Leaf = defineComponent({
|
|
213
|
+
setup() {
|
|
214
|
+
return () => h("div", [h(LeafProbe)]);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
router = new Router({
|
|
218
|
+
mode: RouterMode.memory,
|
|
219
|
+
routes: [
|
|
220
|
+
{
|
|
221
|
+
path: "/level1",
|
|
222
|
+
component: Level1,
|
|
223
|
+
children: [{ path: "leaf", component: Leaf }]
|
|
224
|
+
}
|
|
225
|
+
],
|
|
226
|
+
base: new URL("http://localhost:8000/")
|
|
227
|
+
});
|
|
228
|
+
await router.replace("/level1/leaf");
|
|
229
|
+
const TestApp = defineComponent({
|
|
230
|
+
setup() {
|
|
231
|
+
useProvideRouter(router);
|
|
232
|
+
return () => h("div", [h(RouterView)]);
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
app = createApp(TestApp);
|
|
236
|
+
app.mount("#app");
|
|
237
|
+
await nextTick();
|
|
238
|
+
expect(observedDepth).toBe(2);
|
|
239
|
+
});
|
|
240
|
+
it("should get depth in double-nested RouterViews", async () => {
|
|
241
|
+
let observedDepth;
|
|
242
|
+
const LeafProbe = defineComponent({
|
|
243
|
+
setup() {
|
|
244
|
+
const p = getCurrentInstance().proxy;
|
|
245
|
+
observedDepth = getRouterViewDepth(p);
|
|
246
|
+
return () => h("div");
|
|
247
|
+
}
|
|
248
|
+
});
|
|
249
|
+
const Level1 = defineComponent({
|
|
250
|
+
setup() {
|
|
251
|
+
return () => h("div", [h(RouterView)]);
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
const Level2 = defineComponent({
|
|
255
|
+
setup() {
|
|
256
|
+
return () => h("div", [h(RouterView)]);
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
const Leaf = defineComponent({
|
|
260
|
+
setup() {
|
|
261
|
+
return () => h("div", [h(LeafProbe)]);
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
router = new Router({
|
|
265
|
+
mode: RouterMode.memory,
|
|
266
|
+
routes: [
|
|
267
|
+
{
|
|
268
|
+
path: "/level1",
|
|
269
|
+
component: Level1,
|
|
270
|
+
children: [
|
|
271
|
+
{
|
|
272
|
+
path: "level2",
|
|
273
|
+
component: Level2,
|
|
274
|
+
children: [{ path: "leaf", component: Leaf }]
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
],
|
|
279
|
+
base: new URL("http://localhost:8000/")
|
|
280
|
+
});
|
|
281
|
+
await router.replace("/level1/level2/leaf");
|
|
282
|
+
const TestApp = defineComponent({
|
|
283
|
+
setup() {
|
|
284
|
+
useProvideRouter(router);
|
|
285
|
+
return () => h("div", [h(RouterView)]);
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
app = createApp(TestApp);
|
|
289
|
+
app.mount("#app");
|
|
290
|
+
await nextTick();
|
|
291
|
+
expect(observedDepth).toBe(3);
|
|
292
|
+
});
|
|
293
|
+
it("should throw when no RouterView ancestor exists", async () => {
|
|
294
|
+
let callDepth;
|
|
295
|
+
const Probe = defineComponent({
|
|
296
|
+
setup() {
|
|
297
|
+
const p = getCurrentInstance().proxy;
|
|
298
|
+
callDepth = () => getRouterViewDepth(p);
|
|
299
|
+
return () => h("div");
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
const TestApp = defineComponent({
|
|
303
|
+
setup() {
|
|
304
|
+
useProvideRouter(router);
|
|
305
|
+
return () => h(Probe);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
app = createApp(TestApp);
|
|
309
|
+
app.mount("#app");
|
|
310
|
+
await nextTick();
|
|
311
|
+
expect(() => callDepth()).toThrow(
|
|
312
|
+
new Error(
|
|
313
|
+
"[@esmx/router-vue] RouterView depth not found. Please ensure a RouterView exists in ancestor components."
|
|
314
|
+
)
|
|
315
|
+
);
|
|
316
|
+
});
|
|
317
|
+
it("should return 0 for useRouterViewDepth without RouterView", async () => {
|
|
318
|
+
let observed = -1;
|
|
319
|
+
const Probe = defineComponent({
|
|
320
|
+
setup() {
|
|
321
|
+
observed = useRouterViewDepth();
|
|
322
|
+
return () => h("div");
|
|
323
|
+
}
|
|
324
|
+
});
|
|
325
|
+
const TestApp = defineComponent({
|
|
326
|
+
setup() {
|
|
327
|
+
useProvideRouter(router);
|
|
328
|
+
return () => h(Probe);
|
|
329
|
+
}
|
|
330
|
+
});
|
|
331
|
+
app = createApp(TestApp);
|
|
332
|
+
app.mount("#app");
|
|
333
|
+
await nextTick();
|
|
334
|
+
expect(observed).toBe(0);
|
|
335
|
+
});
|
|
336
|
+
it("should reflect depth via useRouterViewDepth at each level", async () => {
|
|
337
|
+
let level1Depth = -1;
|
|
338
|
+
let level2Depth = -1;
|
|
339
|
+
const Level2 = defineComponent({
|
|
340
|
+
setup() {
|
|
341
|
+
level2Depth = useRouterViewDepth();
|
|
342
|
+
return () => h("div");
|
|
343
|
+
}
|
|
344
|
+
});
|
|
345
|
+
const Level1 = defineComponent({
|
|
346
|
+
setup() {
|
|
347
|
+
level1Depth = useRouterViewDepth();
|
|
348
|
+
return () => h("div", [h(RouterView)]);
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
router = new Router({
|
|
352
|
+
mode: RouterMode.memory,
|
|
353
|
+
routes: [
|
|
354
|
+
{
|
|
355
|
+
path: "/level1",
|
|
356
|
+
component: Level1,
|
|
357
|
+
children: [{ path: "level2", component: Level2 }]
|
|
358
|
+
}
|
|
359
|
+
],
|
|
360
|
+
base: new URL("http://localhost:8000/")
|
|
361
|
+
});
|
|
362
|
+
await router.replace("/level1/level2");
|
|
363
|
+
const TestApp = defineComponent({
|
|
364
|
+
setup() {
|
|
365
|
+
useProvideRouter(router);
|
|
366
|
+
return () => h("div", [h(RouterView)]);
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
app = createApp(TestApp);
|
|
370
|
+
app.mount("#app");
|
|
371
|
+
await nextTick();
|
|
372
|
+
expect(level1Depth).toBe(1);
|
|
373
|
+
expect(level2Depth).toBe(2);
|
|
374
|
+
});
|
|
375
|
+
});
|
|
159
376
|
});
|