头图

angular中,不同路由不同页面之间跳转的时候在不做任何处理的时候是会直接销毁原页面,如果页面没有销毁,那就一定是采用了路由复用。

如下图,在没有采用路由复用的策略的时候,可以看到在页面切换的时候是会直接销毁原页面的。

而采用了路由复用策略以后,可以看到跳转以后,原页面并没有销毁。

要怎么做其实很简单,angular 原生提供了路由相关的接口,首先新建一个ts文件
image.png

然后继承angular提供的路由策略接口
image.png

对接口进行修改,代码如下

import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from "@angular/router";

interface RouterStroageObject {
    snapshot: ActivatedRouteSnapshot;
    handle: DetachedRouteHandle;
}

export class RouterStrategy implements RouteReuseStrategy {

    storedRoutes: { [key: string]: RouterStroageObject } = {};
    storedData: { [key: string]: any } = {};


    /**
     * 
     * 路由离开时是否需要保存页面,这是实现自定义路由复用策略最重要的一个方法。
其中:

返回值为true时,路由离开时保存页面信息,当路由再次激活时,会直接显示保存的页面。

返回值为false时,路由离开时直接销毁组件,当路由再次激活时,直接初始化为新页面。
     */
    shouldDetach(route: ActivatedRouteSnapshot): boolean {
        // console.log('shouldDetach的事件中的route', route)
        if (route.data.noReuse) {
            return false
        }
        return true
    }

    /**
如果shouldDetach方法返回true,会调用这个方法来保存页面。
     */
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        // console.log('store的事件', 'route', route, 'handle', handle);
        const storedRoute: RouterStroageObject = {
            snapshot: route,
            handle: handle
        }
        this.storedRoutes[this.getRouteUrl(route)] = storedRoute;
        // console.log('this.storedRoutes', this.storedRoutes)
    }

    /**
     * 
路由进入页面时是否有页面可以重用。 true: 重用页面,false:生成新的页面
     */
    shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!route.routeConfig && !!this.storedRoutes[this.getRouteUrl(route)];
    }

    /**
     * 
路由激活时获取保存的页面,如果返回null,则生成新页面
     */
    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        if (!route.routeConfig || route.routeConfig.loadChildren || !this.storedRoutes[this.getRouteUrl(route)]) {
            return null
        }
        return this.storedRoutes[this.getRouteUrl(route)].handle
    }

    /**
     * 
     决定跳转后是否可以使用跳转前的路由页面,即跳转前后跳转后使用相同的页面
     */
    shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
    }

    private getRouteUrl(route: ActivatedRouteSnapshot) {
        //@ts-ignore
        const url = route['_routerState'].url;
        const path = url.replace(/\//g, '_') + '_' + (route.routeConfig?.loadChildren || route.routeConfig?.component?.toString().split('(')[0].split(' ')[1]);
        return path
    }

}

保存以后,在要使用的路由文件中引入

import { NgModule } from '@angular/core';
import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router';
import { RouterStrategy } from './routerStrategy';
import { Test1ComponentComponent } from './test1-component/test1-component.component';
import { Test2ComponentComponent } from './test2-component/test2-component.component';

const routes: Routes = [
  { path:'',pathMatch:'full',redirectTo:'/test1' },
  { path:'test1',component:Test1ComponentComponent,data:{noReuse:false} },
  { path:'test2',component:Test2ComponentComponent },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers:[
    {provide:RouteReuseStrategy,useClass:RouterStrategy}
  ]
})
export class AppRoutingModule { }

如果我把noReuse的值改为true那么Test1页面跳转以后就会被销毁,如果设为false或者不设,跳转以后就不会被销毁


munergs
30 声望6 粉丝

现在即是最好。