mirror of
				https://codeberg.org/yeentown/barkey.git
				synced 2025-11-04 15:34:13 +00:00 
			
		
		
		
	feat(frontend/nirax): リダイレクトを設定できるように (#13030)
* feat(frontend/nirax): リダイレクトを設定できるように * revert demonstrative changes * fix * revert unrelated changes * リダイレクトの際にパスが変わらない問題を修正 * リダイレクトが必要なrouteを設定 * fix lint * router向けe2eテストの追加 * fix --------- Co-authored-by: syuilo <Syuilotan@yahoo.co.jp> Co-authored-by: samunohito <46447427+samunohito@users.noreply.github.com>
This commit is contained in:
		
							parent
							
								
									fe7036a1a8
								
							
						
					
					
						commit
						b62d9f3920
					
				
					 4 changed files with 131 additions and 16 deletions
				
			
		
							
								
								
									
										30
									
								
								cypress/e2e/router.cy.js
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								cypress/e2e/router.cy.js
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,30 @@
 | 
				
			||||||
 | 
					describe('Router transition', () => {
 | 
				
			||||||
 | 
						describe('Redirect', () => {
 | 
				
			||||||
 | 
							// サーバの初期化。ルートのテストに関しては各describeごとに1度だけ実行で十分だと思う(使いまわした方が早い)
 | 
				
			||||||
 | 
							before(() => {
 | 
				
			||||||
 | 
								cy.resetState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// インスタンス初期セットアップ
 | 
				
			||||||
 | 
								cy.registerUser('admin', 'pass', true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// ユーザー作成
 | 
				
			||||||
 | 
								cy.registerUser('alice', 'alice1234');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								cy.login('alice', 'alice1234');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// アカウント初期設定ウィザード
 | 
				
			||||||
 | 
								// 表示に時間がかかるのでデフォルト秒数だとタイムアウトする
 | 
				
			||||||
 | 
								cy.get('[data-cy-user-setup] [data-cy-modal-window-close]', { timeout: 12000 }).click();
 | 
				
			||||||
 | 
								cy.wait(500);
 | 
				
			||||||
 | 
								cy.get('[data-cy-modal-dialog-ok]').click();
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							it('redirect to user profile', () => {
 | 
				
			||||||
 | 
								// テストのためだけに用意されたリダイレクト用ルートに飛ぶ
 | 
				
			||||||
 | 
								cy.visit('/redirect-test');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								// プロフィールページのURLであることを確認する
 | 
				
			||||||
 | 
								cy.url().should('include', '/@alice')
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
| 
						 | 
					@ -93,6 +93,13 @@ windowRouter.addListener('push', ctx => {
 | 
				
			||||||
	history.value.push({ path: ctx.path, key: ctx.key });
 | 
						history.value.push({ path: ctx.path, key: ctx.key });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					windowRouter.addListener('replace', ctx => {
 | 
				
			||||||
 | 
						history.value.pop();
 | 
				
			||||||
 | 
						history.value.push({ path: ctx.path, key: ctx.key });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					windowRouter.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
provide('router', windowRouter);
 | 
					provide('router', windowRouter);
 | 
				
			||||||
provideMetadataReceiver((info) => {
 | 
					provideMetadataReceiver((info) => {
 | 
				
			||||||
	pageMetadata.value = info;
 | 
						pageMetadata.value = info;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,7 @@
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { App, AsyncComponentLoader, defineAsyncComponent, provide } from 'vue';
 | 
					import { App, AsyncComponentLoader, defineAsyncComponent, provide } from 'vue';
 | 
				
			||||||
 | 
					import type { RouteDef } from '@/nirax.js';
 | 
				
			||||||
import { IRouter, Router } from '@/nirax.js';
 | 
					import { IRouter, Router } from '@/nirax.js';
 | 
				
			||||||
import { $i, iAmModerator } from '@/account.js';
 | 
					import { $i, iAmModerator } from '@/account.js';
 | 
				
			||||||
import MkLoading from '@/pages/_loading_.vue';
 | 
					import MkLoading from '@/pages/_loading_.vue';
 | 
				
			||||||
| 
						 | 
					@ -16,7 +17,7 @@ const page = (loader: AsyncComponentLoader<any>) => defineAsyncComponent({
 | 
				
			||||||
	errorComponent: MkError,
 | 
						errorComponent: MkError,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const routes = [{
 | 
					const routes: RouteDef[] = [{
 | 
				
			||||||
	path: '/@:initUser/pages/:initPageName/view-source',
 | 
						path: '/@:initUser/pages/:initPageName/view-source',
 | 
				
			||||||
	component: page(() => import('@/pages/page-editor/page-editor.vue')),
 | 
						component: page(() => import('@/pages/page-editor/page-editor.vue')),
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
| 
						 | 
					@ -333,8 +334,7 @@ const routes = [{
 | 
				
			||||||
	component: page(() => import('@/pages/registry.vue')),
 | 
						component: page(() => import('@/pages/registry.vue')),
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
	path: '/install-extentions',
 | 
						path: '/install-extentions',
 | 
				
			||||||
	// Note: This path is kept for compatibility. It may be deleted.
 | 
						redirect: '/install-extensions',
 | 
				
			||||||
	component: page(() => import('@/pages/install-extensions.vue')),
 | 
					 | 
				
			||||||
	loginRequired: true,
 | 
						loginRequired: true,
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
	path: '/install-extensions',
 | 
						path: '/install-extensions',
 | 
				
			||||||
| 
						 | 
					@ -557,6 +557,11 @@ const routes = [{
 | 
				
			||||||
	path: '/',
 | 
						path: '/',
 | 
				
			||||||
	component: $i ? page(() => import('@/pages/timeline.vue')) : page(() => import('@/pages/welcome.vue')),
 | 
						component: $i ? page(() => import('@/pages/timeline.vue')) : page(() => import('@/pages/welcome.vue')),
 | 
				
			||||||
	globalCacheKey: 'index',
 | 
						globalCacheKey: 'index',
 | 
				
			||||||
 | 
					}, {
 | 
				
			||||||
 | 
						// テスト用リダイレクト設定。ログイン中ユーザのプロフィールにリダイレクトする
 | 
				
			||||||
 | 
						path: '/redirect-test',
 | 
				
			||||||
 | 
						redirect: $i ? `@${$i.username}` : '/',
 | 
				
			||||||
 | 
						loginRequired: true,
 | 
				
			||||||
}, {
 | 
					}, {
 | 
				
			||||||
	path: '/:(*)',
 | 
						path: '/:(*)',
 | 
				
			||||||
	component: page(() => import('@/pages/not-found.vue')),
 | 
						component: page(() => import('@/pages/not-found.vue')),
 | 
				
			||||||
| 
						 | 
					@ -575,8 +580,6 @@ export function setupRouter(app: App) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const mainRouter = createRouterImpl(location.pathname + location.search + location.hash);
 | 
						const mainRouter = createRouterImpl(location.pathname + location.search + location.hash);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	window.history.replaceState({ key: mainRouter.getCurrentKey() }, '', location.href);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	window.addEventListener('popstate', (event) => {
 | 
						window.addEventListener('popstate', (event) => {
 | 
				
			||||||
		mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key);
 | 
							mainRouter.replace(location.pathname + location.search + location.hash, event.state?.key);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
| 
						 | 
					@ -585,5 +588,11 @@ export function setupRouter(app: App) {
 | 
				
			||||||
		window.history.pushState({ key: ctx.key }, '', ctx.path);
 | 
							window.history.pushState({ key: ctx.key }, '', ctx.path);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mainRouter.addListener('replace', ctx => {
 | 
				
			||||||
 | 
							window.history.replaceState({ key: ctx.key }, '', ctx.path);
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						mainRouter.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setMainRouter(mainRouter);
 | 
						setMainRouter(mainRouter);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,16 +9,25 @@ import { Component, onMounted, shallowRef, ShallowRef } from 'vue';
 | 
				
			||||||
import { EventEmitter } from 'eventemitter3';
 | 
					import { EventEmitter } from 'eventemitter3';
 | 
				
			||||||
import { safeURIDecode } from '@/scripts/safe-uri-decode.js';
 | 
					import { safeURIDecode } from '@/scripts/safe-uri-decode.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type RouteDef = {
 | 
					interface RouteDefBase {
 | 
				
			||||||
	path: string;
 | 
						path: string;
 | 
				
			||||||
	component: Component;
 | 
					 | 
				
			||||||
	query?: Record<string, string>;
 | 
						query?: Record<string, string>;
 | 
				
			||||||
	loginRequired?: boolean;
 | 
						loginRequired?: boolean;
 | 
				
			||||||
	name?: string;
 | 
						name?: string;
 | 
				
			||||||
	hash?: string;
 | 
						hash?: string;
 | 
				
			||||||
	globalCacheKey?: string;
 | 
						globalCacheKey?: string;
 | 
				
			||||||
	children?: RouteDef[];
 | 
						children?: RouteDef[];
 | 
				
			||||||
};
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface RouteDefWithComponent extends RouteDefBase {
 | 
				
			||||||
 | 
						component: Component,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					interface RouteDefWithRedirect extends RouteDefBase {
 | 
				
			||||||
 | 
						redirect: string | ((props: Map<string, string | boolean>) => string);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type RouteDef = RouteDefWithComponent | RouteDefWithRedirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type ParsedPath = (string | {
 | 
					type ParsedPath = (string | {
 | 
				
			||||||
	name: string;
 | 
						name: string;
 | 
				
			||||||
| 
						 | 
					@ -48,7 +57,19 @@ export type RouterEvent = {
 | 
				
			||||||
	same: () => void;
 | 
						same: () => void;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Resolved = { route: RouteDef; props: Map<string, string | boolean>; child?: Resolved; };
 | 
					export type Resolved = {
 | 
				
			||||||
 | 
						route: RouteDef;
 | 
				
			||||||
 | 
						props: Map<string, string | boolean>;
 | 
				
			||||||
 | 
						child?: Resolved;
 | 
				
			||||||
 | 
						redirected?: boolean;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/** @internal */
 | 
				
			||||||
 | 
						_parsedRoute: {
 | 
				
			||||||
 | 
							fullPath: string;
 | 
				
			||||||
 | 
							queryString: string | null;
 | 
				
			||||||
 | 
							hash: string | null;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function parsePath(path: string): ParsedPath {
 | 
					function parsePath(path: string): ParsedPath {
 | 
				
			||||||
	const res = [] as ParsedPath;
 | 
						const res = [] as ParsedPath;
 | 
				
			||||||
| 
						 | 
					@ -81,6 +102,11 @@ export interface IRouter extends EventEmitter<RouterEvent> {
 | 
				
			||||||
	currentRoute: ShallowRef<RouteDef>;
 | 
						currentRoute: ShallowRef<RouteDef>;
 | 
				
			||||||
	navHook: ((path: string, flag?: any) => boolean) | null;
 | 
						navHook: ((path: string, flag?: any) => boolean) | null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/**
 | 
				
			||||||
 | 
						 * ルートの初期化(eventListenerの定義後に必ず呼び出すこと)
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						init(): void;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	resolve(path: string): Resolved | null;
 | 
						resolve(path: string): Resolved | null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	getCurrentPath(): any;
 | 
						getCurrentPath(): any;
 | 
				
			||||||
| 
						 | 
					@ -156,12 +182,13 @@ export interface IRouter extends EventEmitter<RouterEvent> {
 | 
				
			||||||
export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
					export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
	private routes: RouteDef[];
 | 
						private routes: RouteDef[];
 | 
				
			||||||
	public current: Resolved;
 | 
						public current: Resolved;
 | 
				
			||||||
	public currentRef: ShallowRef<Resolved> = shallowRef();
 | 
						public currentRef: ShallowRef<Resolved>;
 | 
				
			||||||
	public currentRoute: ShallowRef<RouteDef> = shallowRef();
 | 
						public currentRoute: ShallowRef<RouteDef>;
 | 
				
			||||||
	private currentPath: string;
 | 
						private currentPath: string;
 | 
				
			||||||
	private isLoggedIn: boolean;
 | 
						private isLoggedIn: boolean;
 | 
				
			||||||
	private notFoundPageComponent: Component;
 | 
						private notFoundPageComponent: Component;
 | 
				
			||||||
	private currentKey = Date.now().toString();
 | 
						private currentKey = Date.now().toString();
 | 
				
			||||||
 | 
						private redirectCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public navHook: ((path: string, flag?: any) => boolean) | null = null;
 | 
						public navHook: ((path: string, flag?: any) => boolean) | null = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -169,13 +196,24 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
		super();
 | 
							super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		this.routes = routes;
 | 
							this.routes = routes;
 | 
				
			||||||
 | 
							this.current = this.resolve(currentPath)!;
 | 
				
			||||||
 | 
							this.currentRef = shallowRef(this.current);
 | 
				
			||||||
 | 
							this.currentRoute = shallowRef(this.current.route);
 | 
				
			||||||
		this.currentPath = currentPath;
 | 
							this.currentPath = currentPath;
 | 
				
			||||||
		this.isLoggedIn = isLoggedIn;
 | 
							this.isLoggedIn = isLoggedIn;
 | 
				
			||||||
		this.notFoundPageComponent = notFoundPageComponent;
 | 
							this.notFoundPageComponent = notFoundPageComponent;
 | 
				
			||||||
		this.navigate(currentPath, null, false);
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public init() {
 | 
				
			||||||
 | 
							const res = this.navigate(this.currentPath, null, false);
 | 
				
			||||||
 | 
							this.emit('replace', {
 | 
				
			||||||
 | 
								path: res._parsedRoute.fullPath,
 | 
				
			||||||
 | 
								key: this.currentKey,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public resolve(path: string): Resolved | null {
 | 
						public resolve(path: string): Resolved | null {
 | 
				
			||||||
 | 
							const fullPath = path;
 | 
				
			||||||
		let queryString: string | null = null;
 | 
							let queryString: string | null = null;
 | 
				
			||||||
		let hash: string | null = null;
 | 
							let hash: string | null = null;
 | 
				
			||||||
		if (path[0] === '/') path = path.substring(1);
 | 
							if (path[0] === '/') path = path.substring(1);
 | 
				
			||||||
| 
						 | 
					@ -188,6 +226,12 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
			path = path.substring(0, path.indexOf('?'));
 | 
								path = path.substring(0, path.indexOf('?'));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							const _parsedRoute = {
 | 
				
			||||||
 | 
								fullPath,
 | 
				
			||||||
 | 
								queryString,
 | 
				
			||||||
 | 
								hash,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (_DEV_) console.log('Routing: ', path, queryString);
 | 
							if (_DEV_) console.log('Routing: ', path, queryString);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		function check(routes: RouteDef[], _parts: string[]): Resolved | null {
 | 
							function check(routes: RouteDef[], _parts: string[]): Resolved | null {
 | 
				
			||||||
| 
						 | 
					@ -238,6 +282,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
								route,
 | 
													route,
 | 
				
			||||||
								props,
 | 
													props,
 | 
				
			||||||
								child,
 | 
													child,
 | 
				
			||||||
 | 
													_parsedRoute,
 | 
				
			||||||
							};
 | 
												};
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							continue forEachRouteLoop;
 | 
												continue forEachRouteLoop;
 | 
				
			||||||
| 
						 | 
					@ -263,6 +308,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
					return {
 | 
										return {
 | 
				
			||||||
						route,
 | 
											route,
 | 
				
			||||||
						props,
 | 
											props,
 | 
				
			||||||
 | 
											_parsedRoute,
 | 
				
			||||||
					};
 | 
										};
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					if (route.children) {
 | 
										if (route.children) {
 | 
				
			||||||
| 
						 | 
					@ -272,6 +318,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
								route,
 | 
													route,
 | 
				
			||||||
								props,
 | 
													props,
 | 
				
			||||||
								child,
 | 
													child,
 | 
				
			||||||
 | 
													_parsedRoute,
 | 
				
			||||||
							};
 | 
												};
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							continue forEachRouteLoop;
 | 
												continue forEachRouteLoop;
 | 
				
			||||||
| 
						 | 
					@ -290,7 +337,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
		return check(this.routes, _parts);
 | 
							return check(this.routes, _parts);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private navigate(path: string, key: string | null | undefined, emitChange = true) {
 | 
						private navigate(path: string, key: string | null | undefined, emitChange = true, _redirected = false): Resolved {
 | 
				
			||||||
		const beforePath = this.currentPath;
 | 
							const beforePath = this.currentPath;
 | 
				
			||||||
		this.currentPath = path;
 | 
							this.currentPath = path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -300,6 +347,20 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
			throw new Error('no route found for: ' + path);
 | 
								throw new Error('no route found for: ' + path);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if ('redirect' in res.route) {
 | 
				
			||||||
 | 
								let redirectPath: string;
 | 
				
			||||||
 | 
								if (typeof res.route.redirect === 'function') {
 | 
				
			||||||
 | 
									redirectPath = res.route.redirect(res.props);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									redirectPath = res.route.redirect + (res._parsedRoute.queryString ? '?' + res._parsedRoute.queryString : '') + (res._parsedRoute.hash ? '#' + res._parsedRoute.hash : '');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (_DEV_) console.log('Redirecting to: ', redirectPath);
 | 
				
			||||||
 | 
								if (_redirected && this.redirectCount++ > 10) {
 | 
				
			||||||
 | 
									throw new Error('redirect loop detected');
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return this.navigate(redirectPath, null, emitChange, true);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (res.route.loginRequired && !this.isLoggedIn) {
 | 
							if (res.route.loginRequired && !this.isLoggedIn) {
 | 
				
			||||||
			res.route.component = this.notFoundPageComponent;
 | 
								res.route.component = this.notFoundPageComponent;
 | 
				
			||||||
			res.props.set('showLoginPopup', true);
 | 
								res.props.set('showLoginPopup', true);
 | 
				
			||||||
| 
						 | 
					@ -321,7 +382,11 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
			});
 | 
								});
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return res;
 | 
							this.redirectCount = 0;
 | 
				
			||||||
 | 
							return {
 | 
				
			||||||
 | 
								...res,
 | 
				
			||||||
 | 
								redirected: _redirected,
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public getCurrentPath() {
 | 
						public getCurrentPath() {
 | 
				
			||||||
| 
						 | 
					@ -345,7 +410,7 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
		const res = this.navigate(path, null);
 | 
							const res = this.navigate(path, null);
 | 
				
			||||||
		this.emit('push', {
 | 
							this.emit('push', {
 | 
				
			||||||
			beforePath,
 | 
								beforePath,
 | 
				
			||||||
			path,
 | 
								path: res._parsedRoute.fullPath,
 | 
				
			||||||
			route: res.route,
 | 
								route: res.route,
 | 
				
			||||||
			props: res.props,
 | 
								props: res.props,
 | 
				
			||||||
			key: this.currentKey,
 | 
								key: this.currentKey,
 | 
				
			||||||
| 
						 | 
					@ -353,7 +418,11 @@ export class Router extends EventEmitter<RouterEvent> implements IRouter {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public replace(path: string, key?: string | null) {
 | 
						public replace(path: string, key?: string | null) {
 | 
				
			||||||
		this.navigate(path, key);
 | 
							const res = this.navigate(path, key);
 | 
				
			||||||
 | 
							this.emit('replace', {
 | 
				
			||||||
 | 
								path: res._parsedRoute.fullPath,
 | 
				
			||||||
 | 
								key: this.currentKey,
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue