@esmx/router-vue 3.0.0-rc.27 → 3.0.0-rc.30
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/plugin.test.mjs +1 -1
- package/dist/router-link.d.ts +1 -1
- package/dist/use.mjs +10 -8
- package/dist/use.test.mjs +113 -415
- package/dist/util.d.ts +2 -0
- package/dist/util.mjs +8 -0
- package/dist/util.test.mjs +123 -97
- package/package.json +5 -5
- package/src/plugin.test.ts +1 -1
- package/src/use.test.ts +135 -534
- package/src/use.ts +13 -13
- package/src/util.test.ts +128 -111
- package/src/util.ts +13 -0
package/dist/plugin.test.mjs
CHANGED
|
@@ -178,7 +178,7 @@ describe("plugin.ts - RouterPlugin", () => {
|
|
|
178
178
|
app.use(RouterPlugin);
|
|
179
179
|
app.mount(container);
|
|
180
180
|
await nextTick();
|
|
181
|
-
expect(routerResult).
|
|
181
|
+
expect(routerResult).toEqual(router);
|
|
182
182
|
expect(routerResult).toBeInstanceOf(Router);
|
|
183
183
|
});
|
|
184
184
|
it("should actually call $route getter when accessed in component", async () => {
|
package/dist/router-link.d.ts
CHANGED
|
@@ -248,9 +248,9 @@ export declare const RouterLink: import("vue").DefineComponent<import("vue").Ext
|
|
|
248
248
|
type: PropType<(event: Event) => boolean | undefined | void>;
|
|
249
249
|
};
|
|
250
250
|
}>> & Readonly<{}>, {
|
|
251
|
-
type: RouterLinkType;
|
|
252
251
|
replace: boolean;
|
|
253
252
|
exact: RouteMatchType;
|
|
253
|
+
type: RouterLinkType;
|
|
254
254
|
event: string | string[];
|
|
255
255
|
tag: string;
|
|
256
256
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
package/dist/use.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
provide,
|
|
7
7
|
ref
|
|
8
8
|
} from "vue";
|
|
9
|
-
import { createSymbolProperty } from "./util.mjs";
|
|
9
|
+
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 ERROR_MESSAGES = {
|
|
@@ -44,7 +44,7 @@ export function getRouter(instance) {
|
|
|
44
44
|
return findRouterContext(instance).router;
|
|
45
45
|
}
|
|
46
46
|
export function getRoute(instance) {
|
|
47
|
-
return findRouterContext(instance).route
|
|
47
|
+
return findRouterContext(instance).route;
|
|
48
48
|
}
|
|
49
49
|
function useRouterContext(functionName) {
|
|
50
50
|
const injectedContext = inject(ROUTER_INJECT_KEY);
|
|
@@ -58,28 +58,30 @@ export function useRouter() {
|
|
|
58
58
|
return useRouterContext("useRouter").router;
|
|
59
59
|
}
|
|
60
60
|
export function useRoute() {
|
|
61
|
-
return useRouterContext("useRoute").route
|
|
61
|
+
return useRouterContext("useRoute").route;
|
|
62
62
|
}
|
|
63
63
|
export function useProvideRouter(router) {
|
|
64
64
|
const proxy = getCurrentProxy("useProvideRouter");
|
|
65
|
+
const dep = ref(false);
|
|
66
|
+
const proxiedRouter = createDependentProxy(router, dep);
|
|
67
|
+
const proxiedRoute = createDependentProxy(router.route, dep);
|
|
65
68
|
const context = {
|
|
66
|
-
router,
|
|
67
|
-
route:
|
|
69
|
+
router: proxiedRouter,
|
|
70
|
+
route: proxiedRoute
|
|
68
71
|
};
|
|
69
72
|
provide(ROUTER_INJECT_KEY, context);
|
|
70
73
|
routerContextProperty.set(proxy, context);
|
|
71
74
|
const unwatch = router.afterEach((to) => {
|
|
72
75
|
if (router.route === to) {
|
|
73
|
-
to.syncTo(
|
|
76
|
+
to.syncTo(proxiedRoute);
|
|
77
|
+
dep.value = !dep.value;
|
|
74
78
|
}
|
|
75
79
|
});
|
|
76
80
|
onBeforeUnmount(unwatch);
|
|
77
81
|
}
|
|
78
82
|
export function useLink(props) {
|
|
79
83
|
const router = useRouter();
|
|
80
|
-
const route = useRoute();
|
|
81
84
|
return computed(() => {
|
|
82
|
-
route.fullPath;
|
|
83
85
|
return router.resolveLink(props);
|
|
84
86
|
});
|
|
85
87
|
}
|
package/dist/use.test.mjs
CHANGED
|
@@ -1,461 +1,159 @@
|
|
|
1
1
|
import { Router, RouterMode } from "@esmx/router";
|
|
2
2
|
import { afterEach, beforeEach, describe, expect, it } from "vitest";
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
nextTick
|
|
9
|
-
} from "vue";
|
|
10
|
-
import {
|
|
11
|
-
getRoute,
|
|
12
|
-
getRouter,
|
|
13
|
-
useLink,
|
|
14
|
-
useProvideRouter,
|
|
15
|
-
useRoute,
|
|
16
|
-
useRouter
|
|
17
|
-
} from "./use.mjs";
|
|
18
|
-
describe("use.ts - Vue Router Integration", () => {
|
|
3
|
+
import { nextTick } from "vue";
|
|
4
|
+
import { createApp, h } from "vue";
|
|
5
|
+
import { useProvideRouter, useRoute, useRouter } from "./use.mjs";
|
|
6
|
+
describe("Router Vue Integration", () => {
|
|
7
|
+
let app;
|
|
19
8
|
let router;
|
|
20
|
-
let
|
|
9
|
+
let mountPoint;
|
|
21
10
|
beforeEach(async () => {
|
|
22
|
-
testContainer = document.createElement("div");
|
|
23
|
-
testContainer.id = "test-app";
|
|
24
|
-
document.body.appendChild(testContainer);
|
|
25
|
-
const routes = [
|
|
26
|
-
{
|
|
27
|
-
path: "/",
|
|
28
|
-
component: defineComponent({ template: "<div>Home</div>" }),
|
|
29
|
-
meta: { title: "Home" }
|
|
30
|
-
},
|
|
31
|
-
{
|
|
32
|
-
path: "/about",
|
|
33
|
-
component: defineComponent({ template: "<div>About</div>" }),
|
|
34
|
-
meta: { title: "About" }
|
|
35
|
-
}
|
|
36
|
-
];
|
|
37
11
|
router = new Router({
|
|
38
|
-
root: "#test-app",
|
|
39
|
-
routes,
|
|
40
12
|
mode: RouterMode.memory,
|
|
13
|
+
routes: [
|
|
14
|
+
{ path: "/initial", component: {} },
|
|
15
|
+
{ path: "/new-route", component: {} },
|
|
16
|
+
{ path: "/user/:id", component: {} },
|
|
17
|
+
{ path: "/new-path", component: {} }
|
|
18
|
+
],
|
|
41
19
|
base: new URL("http://localhost:3000/")
|
|
42
20
|
});
|
|
43
|
-
await router.replace("/");
|
|
21
|
+
await router.replace("/initial");
|
|
22
|
+
mountPoint = document.createElement("div");
|
|
23
|
+
mountPoint.id = "app";
|
|
24
|
+
document.body.appendChild(mountPoint);
|
|
44
25
|
});
|
|
45
26
|
afterEach(() => {
|
|
46
|
-
if (
|
|
47
|
-
testContainer.parentNode.removeChild(testContainer);
|
|
48
|
-
}
|
|
49
|
-
if (router) {
|
|
50
|
-
router.destroy();
|
|
51
|
-
}
|
|
52
|
-
});
|
|
53
|
-
describe("Error Handling - Context Not Found", () => {
|
|
54
|
-
const contextNotFoundError = "[@esmx/router-vue] Router context not found. Please ensure useProvideRouter() is called in a parent component.";
|
|
55
|
-
const contextErrorTestCases = [
|
|
56
|
-
{
|
|
57
|
-
name: "getRouter called without router context",
|
|
58
|
-
test: () => {
|
|
59
|
-
const app = createApp({ template: "<div>Test</div>" });
|
|
60
|
-
const vm = app.mount(testContainer);
|
|
61
|
-
const result = () => getRouter(vm);
|
|
62
|
-
app.unmount();
|
|
63
|
-
return result;
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "getRoute called without router context",
|
|
68
|
-
test: () => {
|
|
69
|
-
const app = createApp({ template: "<div>Test</div>" });
|
|
70
|
-
const vm = app.mount(testContainer);
|
|
71
|
-
const result = () => getRoute(vm);
|
|
72
|
-
app.unmount();
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
];
|
|
77
|
-
contextErrorTestCases.forEach(({ name, test }) => {
|
|
78
|
-
it("should throw error when ".concat(name), () => {
|
|
79
|
-
expect(test()).toThrow(contextNotFoundError);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
const compositionContextErrorTestCases = [
|
|
83
|
-
{
|
|
84
|
-
name: "useRouter called without router context",
|
|
85
|
-
setupFn: () => {
|
|
86
|
-
expect(() => useRouter()).toThrow(contextNotFoundError);
|
|
87
|
-
}
|
|
88
|
-
},
|
|
89
|
-
{
|
|
90
|
-
name: "useRoute called without router context",
|
|
91
|
-
setupFn: () => {
|
|
92
|
-
expect(() => useRoute()).toThrow(contextNotFoundError);
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
name: "useLink called without router context",
|
|
97
|
-
setupFn: () => {
|
|
98
|
-
expect(
|
|
99
|
-
() => useLink({
|
|
100
|
-
to: "/about",
|
|
101
|
-
type: "push",
|
|
102
|
-
exact: "include"
|
|
103
|
-
})
|
|
104
|
-
).toThrow(contextNotFoundError);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
];
|
|
108
|
-
compositionContextErrorTestCases.forEach(({ name, setupFn }) => {
|
|
109
|
-
it("should throw error when ".concat(name), () => {
|
|
110
|
-
const TestComponent = defineComponent({
|
|
111
|
-
setup() {
|
|
112
|
-
setupFn();
|
|
113
|
-
return () => "<div>Test</div>";
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
const app = createApp(TestComponent);
|
|
117
|
-
app.mount(testContainer);
|
|
118
|
-
app.unmount();
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
describe("Error Handling - Setup Only", () => {
|
|
123
|
-
const setupOnlyTestCases = [
|
|
124
|
-
{
|
|
125
|
-
name: "useRouter called outside setup()",
|
|
126
|
-
fn: () => useRouter(),
|
|
127
|
-
expectedError: "[@esmx/router-vue] useRouter() can only be called during setup()"
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: "useRoute called outside setup()",
|
|
131
|
-
fn: () => useRoute(),
|
|
132
|
-
expectedError: "[@esmx/router-vue] useRoute() can only be called during setup()"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "useLink called outside setup()",
|
|
136
|
-
fn: () => useLink({
|
|
137
|
-
to: "/about",
|
|
138
|
-
type: "push",
|
|
139
|
-
exact: "include"
|
|
140
|
-
}),
|
|
141
|
-
expectedError: "[@esmx/router-vue] useRouter() can only be called during setup()"
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
name: "useProvideRouter called outside setup()",
|
|
145
|
-
fn: () => useProvideRouter(router),
|
|
146
|
-
expectedError: "[@esmx/router-vue] useProvideRouter() can only be called during setup()"
|
|
147
|
-
}
|
|
148
|
-
];
|
|
149
|
-
setupOnlyTestCases.forEach(({ name, fn, expectedError }) => {
|
|
150
|
-
it("should throw error when ".concat(name), () => {
|
|
151
|
-
expect(fn).toThrow(expectedError);
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
});
|
|
155
|
-
describe("Basic Functionality", () => {
|
|
156
|
-
it("should provide router context and return router instance from getRouter", async () => {
|
|
157
|
-
let routerInstance = null;
|
|
158
|
-
const app = createApp({
|
|
159
|
-
setup() {
|
|
160
|
-
useProvideRouter(router);
|
|
161
|
-
return () => "<div>App</div>";
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
const vm = app.mount(testContainer);
|
|
165
|
-
routerInstance = getRouter(vm);
|
|
166
|
-
expect(routerInstance).toBe(router);
|
|
167
|
-
expect(routerInstance).toBeInstanceOf(Router);
|
|
168
|
-
app.unmount();
|
|
169
|
-
});
|
|
170
|
-
it("should provide router context and return current route from getRoute", async () => {
|
|
171
|
-
let currentRoute = null;
|
|
172
|
-
const app = createApp({
|
|
173
|
-
setup() {
|
|
174
|
-
useProvideRouter(router);
|
|
175
|
-
return () => "<div>App</div>";
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
const vm = app.mount(testContainer);
|
|
179
|
-
currentRoute = getRoute(vm);
|
|
180
|
-
expect(currentRoute).toBeTruthy();
|
|
181
|
-
expect(currentRoute.path).toBe("/");
|
|
182
|
-
expect(currentRoute.meta.title).toBe("Home");
|
|
27
|
+
if (app) {
|
|
183
28
|
app.unmount();
|
|
184
|
-
}
|
|
29
|
+
}
|
|
30
|
+
document.body.removeChild(mountPoint);
|
|
31
|
+
router.destroy();
|
|
185
32
|
});
|
|
186
|
-
describe("
|
|
187
|
-
it("should
|
|
188
|
-
let
|
|
189
|
-
let
|
|
190
|
-
const
|
|
191
|
-
name: "ChildComponent",
|
|
192
|
-
setup() {
|
|
193
|
-
routerInstance = useRouter();
|
|
194
|
-
childRoute = useRoute();
|
|
195
|
-
expect(routerInstance).toBe(router);
|
|
196
|
-
expect(childRoute.path).toBe("/");
|
|
197
|
-
return () => h("div", "Child Component");
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
const ParentComponent = defineComponent({
|
|
201
|
-
name: "ParentComponent",
|
|
202
|
-
components: { ChildComponent },
|
|
33
|
+
describe("Router and Route Access", () => {
|
|
34
|
+
it("should provide router and route access", async () => {
|
|
35
|
+
let routerResult;
|
|
36
|
+
let routeResult;
|
|
37
|
+
const TestApp = {
|
|
203
38
|
setup() {
|
|
204
39
|
useProvideRouter(router);
|
|
205
|
-
|
|
40
|
+
routerResult = useRouter();
|
|
41
|
+
routeResult = useRoute();
|
|
42
|
+
return () => h("div", "Test App");
|
|
206
43
|
}
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
app.mount(
|
|
210
|
-
|
|
211
|
-
expect(
|
|
212
|
-
expect(
|
|
213
|
-
expect(childRoute.path).toBe("/");
|
|
214
|
-
app.unmount();
|
|
215
|
-
});
|
|
216
|
-
it("should work with nested components in setup()", async () => {
|
|
217
|
-
let deepChildRouter = null;
|
|
218
|
-
const DeepChildComponent = defineComponent({
|
|
219
|
-
name: "DeepChildComponent",
|
|
220
|
-
setup() {
|
|
221
|
-
deepChildRouter = useRouter();
|
|
222
|
-
expect(deepChildRouter).toBe(router);
|
|
223
|
-
return () => h("div", "Deep Child");
|
|
224
|
-
}
|
|
225
|
-
});
|
|
226
|
-
const MiddleComponent = defineComponent({
|
|
227
|
-
name: "MiddleComponent",
|
|
228
|
-
components: { DeepChildComponent },
|
|
229
|
-
setup() {
|
|
230
|
-
return () => h(DeepChildComponent);
|
|
231
|
-
}
|
|
232
|
-
});
|
|
233
|
-
const TopComponent = defineComponent({
|
|
234
|
-
name: "TopComponent",
|
|
235
|
-
components: { MiddleComponent },
|
|
236
|
-
setup() {
|
|
237
|
-
useProvideRouter(router);
|
|
238
|
-
return () => h(MiddleComponent);
|
|
239
|
-
}
|
|
240
|
-
});
|
|
241
|
-
const app = createApp(TopComponent);
|
|
242
|
-
app.mount(testContainer);
|
|
243
|
-
await nextTick();
|
|
244
|
-
expect(deepChildRouter).toBe(router);
|
|
245
|
-
app.unmount();
|
|
44
|
+
};
|
|
45
|
+
app = createApp(TestApp);
|
|
46
|
+
app.mount("#app");
|
|
47
|
+
expect(routerResult).toEqual(router);
|
|
48
|
+
expect(routeResult).toBeDefined();
|
|
49
|
+
expect(routeResult == null ? void 0 : routeResult.path).toBe("/initial");
|
|
246
50
|
});
|
|
247
51
|
});
|
|
248
|
-
describe("
|
|
249
|
-
it("should
|
|
250
|
-
let
|
|
251
|
-
|
|
252
|
-
let childVmInstance = null;
|
|
253
|
-
const ChildComponent = defineComponent({
|
|
254
|
-
name: "ChildComponent",
|
|
255
|
-
setup(_, { expose }) {
|
|
256
|
-
const instance = getCurrentInstance();
|
|
257
|
-
childVmInstance = (instance == null ? void 0 : instance.proxy) || null;
|
|
258
|
-
try {
|
|
259
|
-
childRouterResult = useRouter();
|
|
260
|
-
} catch (error) {
|
|
261
|
-
expect(error.message).toContain(
|
|
262
|
-
"Router context not found"
|
|
263
|
-
);
|
|
264
|
-
}
|
|
265
|
-
expose({ childVmInstance });
|
|
266
|
-
return () => "<div>Child Component</div>";
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
const ParentComponent = defineComponent({
|
|
270
|
-
name: "ParentComponent",
|
|
271
|
-
components: { ChildComponent },
|
|
272
|
-
setup(_, { expose }) {
|
|
273
|
-
const instance = getCurrentInstance();
|
|
274
|
-
parentVmInstance = (instance == null ? void 0 : instance.proxy) || null;
|
|
275
|
-
useProvideRouter(router);
|
|
276
|
-
expose({ parentVmInstance });
|
|
277
|
-
return () => h(ChildComponent);
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
const app = createApp(ParentComponent);
|
|
281
|
-
const mountedApp = app.mount(testContainer);
|
|
282
|
-
await nextTick();
|
|
283
|
-
if (childVmInstance && parentVmInstance) {
|
|
284
|
-
const parentHasContext = !!parentVmInstance[Symbol.for("router-context")] || Object.getOwnPropertySymbols(parentVmInstance).some(
|
|
285
|
-
(sym) => sym.toString().includes("router-context")
|
|
286
|
-
);
|
|
287
|
-
expect(parentHasContext).toBe(true);
|
|
288
|
-
}
|
|
289
|
-
if (childRouterResult) {
|
|
290
|
-
expect(childRouterResult).toBe(router);
|
|
291
|
-
}
|
|
292
|
-
app.unmount();
|
|
293
|
-
});
|
|
294
|
-
it("should investigate direct getRouter call with component instances", async () => {
|
|
295
|
-
let parentInstance = null;
|
|
296
|
-
let childInstance = null;
|
|
297
|
-
const ChildComponent = defineComponent({
|
|
298
|
-
name: "ChildComponent",
|
|
52
|
+
describe("Route Reactivity", () => {
|
|
53
|
+
it("should update route properties when route changes", async () => {
|
|
54
|
+
let routeRef;
|
|
55
|
+
const TestApp = {
|
|
299
56
|
setup() {
|
|
300
|
-
const instance = getCurrentInstance();
|
|
301
|
-
childInstance = (instance == null ? void 0 : instance.proxy) || null;
|
|
302
|
-
return () => "<div>Child</div>";
|
|
303
|
-
}
|
|
304
|
-
});
|
|
305
|
-
const ParentComponent = defineComponent({
|
|
306
|
-
name: "ParentComponent",
|
|
307
|
-
components: { ChildComponent },
|
|
308
|
-
setup() {
|
|
309
|
-
const instance = getCurrentInstance();
|
|
310
|
-
parentInstance = (instance == null ? void 0 : instance.proxy) || null;
|
|
311
57
|
useProvideRouter(router);
|
|
312
|
-
|
|
58
|
+
routeRef = useRoute();
|
|
59
|
+
return () => h("div", routeRef == null ? void 0 : routeRef.path);
|
|
313
60
|
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
app.mount(
|
|
61
|
+
};
|
|
62
|
+
app = createApp(TestApp);
|
|
63
|
+
app.mount("#app");
|
|
64
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/initial");
|
|
65
|
+
const initialRouteRef = routeRef;
|
|
66
|
+
await router.replace("/new-route");
|
|
317
67
|
await nextTick();
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const routerFromChild = getRouter(childInstance);
|
|
321
|
-
expect(routerFromChild).toBe(router);
|
|
322
|
-
} catch (error) {
|
|
323
|
-
expect(error.message).toContain(
|
|
324
|
-
"Router context not found"
|
|
325
|
-
);
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
app.unmount();
|
|
68
|
+
expect(routeRef).toBe(initialRouteRef);
|
|
69
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/new-route");
|
|
329
70
|
});
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
const
|
|
334
|
-
setup() {
|
|
335
|
-
useProvideRouter(router);
|
|
336
|
-
return () => "<div>App</div>";
|
|
337
|
-
}
|
|
338
|
-
});
|
|
339
|
-
app.mount(testContainer);
|
|
340
|
-
expect(router.route.path).toBe("/");
|
|
341
|
-
expect(router.route.meta.title).toBe("Home");
|
|
342
|
-
await router.push("/about");
|
|
343
|
-
expect(router.route.path).toBe("/about");
|
|
344
|
-
expect(router.route.meta.title).toBe("About");
|
|
345
|
-
app.unmount();
|
|
346
|
-
});
|
|
347
|
-
});
|
|
348
|
-
describe("Composition API Integration", () => {
|
|
349
|
-
it("should work with composition API functions in same component", async () => {
|
|
350
|
-
let compositionRouter = null;
|
|
351
|
-
let compositionRoute = null;
|
|
352
|
-
let linkResolver = null;
|
|
353
|
-
const TestComponent = defineComponent({
|
|
71
|
+
it("should update route params when route changes", async () => {
|
|
72
|
+
var _a;
|
|
73
|
+
let routeRef;
|
|
74
|
+
const TestApp = {
|
|
354
75
|
setup() {
|
|
355
76
|
useProvideRouter(router);
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
77
|
+
routeRef = useRoute();
|
|
78
|
+
return () => {
|
|
79
|
+
var _a2;
|
|
80
|
+
return h("div", [
|
|
81
|
+
h("span", routeRef == null ? void 0 : routeRef.path),
|
|
82
|
+
h("span", ((_a2 = routeRef == null ? void 0 : routeRef.params) == null ? void 0 : _a2.id) || "no-id")
|
|
83
|
+
]);
|
|
84
|
+
};
|
|
364
85
|
}
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
app.mount(
|
|
86
|
+
};
|
|
87
|
+
app = createApp(TestApp);
|
|
88
|
+
app.mount("#app");
|
|
89
|
+
await router.replace("/user/123");
|
|
368
90
|
await nextTick();
|
|
369
|
-
expect(
|
|
370
|
-
expect(
|
|
371
|
-
expect(compositionRoute.path).toBe("/");
|
|
372
|
-
expect(compositionRoute.meta.title).toBe("Home");
|
|
373
|
-
expect(linkResolver).toBeTruthy();
|
|
374
|
-
expect(linkResolver.value).toBeTruthy();
|
|
375
|
-
const link = linkResolver.value;
|
|
376
|
-
expect(link).toHaveProperty("attributes");
|
|
377
|
-
expect(link).toHaveProperty("getEventHandlers");
|
|
378
|
-
expect(link).toHaveProperty("isActive");
|
|
379
|
-
app.unmount();
|
|
91
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/user/123");
|
|
92
|
+
expect((_a = routeRef == null ? void 0 : routeRef.params) == null ? void 0 : _a.id).toBe("123");
|
|
380
93
|
});
|
|
381
|
-
it("should
|
|
382
|
-
|
|
383
|
-
|
|
94
|
+
it("should automatically update view when route changes", async () => {
|
|
95
|
+
const renderCount = { value: 0 };
|
|
96
|
+
let routeRef;
|
|
97
|
+
const TestApp = {
|
|
384
98
|
setup() {
|
|
385
99
|
useProvideRouter(router);
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
100
|
+
routeRef = useRoute();
|
|
101
|
+
return () => {
|
|
102
|
+
renderCount.value++;
|
|
103
|
+
return h("div", routeRef == null ? void 0 : routeRef.path);
|
|
104
|
+
};
|
|
389
105
|
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
app.mount(
|
|
106
|
+
};
|
|
107
|
+
app = createApp(TestApp);
|
|
108
|
+
app.mount("#app");
|
|
109
|
+
const initialRenderCount = renderCount.value;
|
|
110
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/initial");
|
|
111
|
+
await router.replace("/new-route");
|
|
393
112
|
await nextTick();
|
|
394
|
-
expect(
|
|
395
|
-
expect(routeRef.path).toBe("/");
|
|
396
|
-
|
|
113
|
+
expect(renderCount.value).toBeGreaterThan(initialRenderCount);
|
|
114
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/new-route");
|
|
115
|
+
const previousRenderCount = renderCount.value;
|
|
116
|
+
await router.replace("/new-path");
|
|
397
117
|
await nextTick();
|
|
398
|
-
expect(
|
|
399
|
-
|
|
118
|
+
expect(renderCount.value).toBeGreaterThan(previousRenderCount);
|
|
119
|
+
expect(routeRef == null ? void 0 : routeRef.path).toBe("/new-path");
|
|
400
120
|
});
|
|
401
121
|
});
|
|
402
|
-
describe("
|
|
403
|
-
it("should
|
|
404
|
-
let
|
|
405
|
-
|
|
406
|
-
|
|
122
|
+
describe("Nested Components", () => {
|
|
123
|
+
it("should provide route context to child components", async () => {
|
|
124
|
+
let parentRoute;
|
|
125
|
+
let childRoute;
|
|
126
|
+
const ChildComponent = {
|
|
407
127
|
setup() {
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
});
|
|
411
|
-
const ParentComponent = defineComponent({
|
|
412
|
-
name: "ParentComponent",
|
|
413
|
-
setup() {
|
|
414
|
-
return () => h(ChildComponent);
|
|
128
|
+
childRoute = useRoute();
|
|
129
|
+
return () => h("div", "Child: " + (childRoute == null ? void 0 : childRoute.path));
|
|
415
130
|
}
|
|
416
|
-
}
|
|
417
|
-
const
|
|
418
|
-
name: "GrandParentComponent",
|
|
131
|
+
};
|
|
132
|
+
const ParentComponent = {
|
|
419
133
|
setup() {
|
|
420
|
-
|
|
421
|
-
return () => h(
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
const mountedApp = app.mount(testContainer);
|
|
426
|
-
await nextTick();
|
|
427
|
-
const deepChildInstance = mountedApp;
|
|
428
|
-
const mockDeepChild = {
|
|
429
|
-
$parent: {
|
|
430
|
-
// This is the middle parent (no router context)
|
|
431
|
-
$parent: mountedApp
|
|
432
|
-
// This is the grandparent (has router context)
|
|
134
|
+
parentRoute = useRoute();
|
|
135
|
+
return () => h("div", [
|
|
136
|
+
h("span", "Parent: " + (parentRoute == null ? void 0 : parentRoute.path)),
|
|
137
|
+
h(ChildComponent)
|
|
138
|
+
]);
|
|
433
139
|
}
|
|
434
140
|
};
|
|
435
|
-
|
|
436
|
-
expect(childRouterResult).toBe(router);
|
|
437
|
-
expect(childRouterResult).toBeInstanceOf(Router);
|
|
438
|
-
app.unmount();
|
|
439
|
-
});
|
|
440
|
-
it("should handle component hierarchy traversal with manual parent chain setup", () => {
|
|
441
|
-
const app = createApp({
|
|
141
|
+
const TestApp = {
|
|
442
142
|
setup() {
|
|
443
143
|
useProvideRouter(router);
|
|
444
|
-
return () => h(
|
|
445
|
-
}
|
|
446
|
-
});
|
|
447
|
-
const rootInstance = app.mount(testContainer);
|
|
448
|
-
const leafInstance = {
|
|
449
|
-
$parent: {
|
|
450
|
-
// Middle level - no router context
|
|
451
|
-
$parent: rootInstance
|
|
452
|
-
// Root level - has router context
|
|
144
|
+
return () => h(ParentComponent);
|
|
453
145
|
}
|
|
454
146
|
};
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
expect(
|
|
458
|
-
|
|
147
|
+
app = createApp(TestApp);
|
|
148
|
+
app.mount("#app");
|
|
149
|
+
expect(parentRoute).toBeDefined();
|
|
150
|
+
expect(childRoute).toBeDefined();
|
|
151
|
+
expect(parentRoute == null ? void 0 : parentRoute.path).toBe("/initial");
|
|
152
|
+
expect(childRoute == null ? void 0 : childRoute.path).toBe("/initial");
|
|
153
|
+
await router.replace("/new-path");
|
|
154
|
+
await nextTick();
|
|
155
|
+
expect(parentRoute == null ? void 0 : parentRoute.path).toBe("/new-path");
|
|
156
|
+
expect(childRoute == null ? void 0 : childRoute.path).toBe("/new-path");
|
|
459
157
|
});
|
|
460
158
|
});
|
|
461
159
|
});
|
package/dist/util.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import type { Ref } from 'vue';
|
|
1
2
|
export declare const isVue3: boolean;
|
|
2
3
|
export declare function createSymbolProperty<T>(symbol: symbol): {
|
|
3
4
|
readonly set: (instance: any, value: T) => void;
|
|
4
5
|
readonly get: (instance: any) => T | undefined;
|
|
5
6
|
};
|
|
7
|
+
export declare function createDependentProxy<T extends object>(obj: T, dep: Ref<boolean>): T;
|
|
6
8
|
export declare function isESModule(obj: unknown): obj is Record<string | symbol, any>;
|
|
7
9
|
export declare function resolveComponent(component: unknown): unknown;
|
package/dist/util.mjs
CHANGED
|
@@ -10,6 +10,14 @@ export function createSymbolProperty(symbol) {
|
|
|
10
10
|
}
|
|
11
11
|
};
|
|
12
12
|
}
|
|
13
|
+
export function createDependentProxy(obj, dep) {
|
|
14
|
+
return new Proxy(obj, {
|
|
15
|
+
get(target, prop, receiver) {
|
|
16
|
+
dep.value;
|
|
17
|
+
return Reflect.get(target, prop, receiver);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
13
21
|
export function isESModule(obj) {
|
|
14
22
|
if (!obj || typeof obj !== "object") return false;
|
|
15
23
|
const module = obj;
|