# reuse-tab **Repository Path**: ccteams/reuse-tab ## Basic Information - **Project Name**: reuse-tab - **Description**: Angular Material reuse route tab - **Primary Language**: TypeScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 4 - **Forks**: 3 - **Created**: 2018-12-02 - **Last Updated**: 2022-01-06 ## Categories & Tags **Categories**: angular-extensions, webui **Tags**: None ## README --- title: reuse-tab subtitle: 路由复用标签 cols: 1 module: AdReuseTabModule --- 复用标签在中台系统非常常见,本质是解决不同路由页切换时组件数据不丢失问题。 最新打开的永远是当前页,而路由复用是指当我们离开当前页时若符合复用条件(即:匹配模式)则保存当前路由所有组件状态(包括子组件),待下一次进入相同路由(即:匹配模式)时再从中缓存中获取到。 ## 如何使用? ``` npm install --save reuse-tab ``` 默认 `AdReuseTabModule` 并不会注册 `RouteReuseStrategy`,除了引入模块以外,还需要在**手动注册** `RouteReuseStrategy`。 ```ts // delon.module.ts or app.module.ts providers: [ { provide: RouteReuseStrategy, useClass: ReuseTabStrategy, deps: [ReuseTabService], }, ReuseTabService ] ``` ## 匹配模式 在项目的任何位置(建议:`startup.service.ts`)注入 `ReuseTabService` 类,并设置 `mode` 属性,或通过 `` 重新设置值,包括: **0、(推荐,默认值)** 可复用: ``` { text:'Dashboard' } { text:'Dashboard', reuse: true } ``` 不可复用: ``` { text:'Dashboard', reuse: false } ``` **1、(推荐)** 可复用: ``` { text:'Dashboard', reuse: true } ``` 不可复用: ``` { text:'Dashboard' } { text:'Dashboard', reuse: false } ``` **2、URL** 对所有路由有效,可以配合 `excludes` 过滤无须复用路由。 > 除以上规则以外,路由配置中 `data` 属性若设置 `reuse` 值时优先级高于上述规则。 ## 标签文本 根据以下顺序获取标签文本: 1. 组件内使用 `ReuseTabService.title = 'new title'` 重新指定文本, 2. 路由配置中 `data` 属性中包含 `reuseTitle` > `title` 3. 菜单数据中 `text` 属性 `ReuseTabService` 代码示例: ```ts export class DemoReuseTabEditComponent implements OnInit { id: any; constructor(private route: ActivatedRoute, private reuseTabService: ReuseTabService) {} ngOnInit(): void { this.route.params.subscribe(params => { this.id = params.id; this.reuseTabService.title = `编辑 ${this.id}`; }); } } ``` ## 生命周期 路由复用过程中不会触发现有任何生命周期钩子(例如:`ngOnInit` 等),但是往往需要在复用过程中刷新数据,因此 `reuse-tab` 提供了两种新生命周期钩子用于临时解决这类问题。 **_onReuseInit()** 当目前路由在复用过程中时触发。 **_onReuseDestroy()** 当目前路由允许复用且进入新路由时触发。 以 `_` 开头希望未来 Angular 会有相应的钩子用于快速替换,一个简单的示例: ```ts @Component() export class DemoComponent { _onReuseInit() { console.log('_onReuseInit'); } _onReuseDestroy() { console.log('_onReuseDestroy'); } } ``` ## 常见问题 ### 如何Debug? 路由复用会保留组件状态,这可能会带来另一个弊端;复用过程中组件的生命周期勾子不会重复触发,大部分情况下都能正常运行,但可能需要注意: - `OnDestroy` 可能会处理一些组件外部(例如:`body`)的样式等,可以参考生命周期解决。 - 开启 `debug` 模式后会在 `console` 很多信息这有助于分析路由复用的过程。 ## API ### ReuseTabService 接口 **属性** 参数 | 说明 | 类型 | 默认值 ----|------|-----|------ `[mode]` | 设置匹配模式 | `ReuseTabMatchMode` | `0` `[debug]` | 是否Debug模式 | `boolean` | `false` `[excludes]` | 排除规则,限 `mode=URL` | `RegExp[]` | - `[items]` | 获取已缓存的路由 | `ReuseTabCached[]` | - `[count]` | 获取当前缓存的路由总数 | `number` | - `[change]` | 订阅缓存变更通知 | `Observable` | - `[title]` | 自定义当前标题 | `string` | - `[closable]` | 自定义当前 `closable` 状态 | `boolean` | - **方法** 方法名 | 说明 | 返回类型 ----|------|----- `index(url)` | 获取指定路径缓存所在位置,`-1` 表示无缓存 | `number` `exists(url)` | 获取指定路径缓存是否存在 | `boolean` `get(url)` | 获取指定路径缓存 | `boolean` `getTitle(url, route?: ActivatedRouteSnapshot)` | 获取标题 | `string` `clearTitleCached()` | 清空自定义标题数据 | `void` `getClosable(url, route?: ActivatedRouteSnapshot)` | 获取 `closable` 状态 | `string` `clearClosableCached()` | 清空 `closable` 缓存 | `void` `remove(url)` | 根据URL移除标签,同时触 `change` remove事件 | `void` `move(url, position)` | 移动缓存数据,同时触 `change` move事件 | `void` `clear()` | 清除所有缓存,同时触 `change` clear事件 | `void` `refresh()` | 无任何动作,但会触 `change` refresh事件 | `void` `replace(url)` | 强制关闭当前路由(包含不可关闭状态),并重新导航至 `newUrl` 路由 | `void` ### reuse-tab 组件 参数 | 说明 | 类型 | 默认值 ----|------|-----|------ `[mode]` | 设置匹配模式 | `ReuseTabMatchMode` | `0` `[debug]` | 是否Debug模式 | `boolean` | `false` `[max]` | 允许最多复用多少个页面 | `number` | `10` `[excludes]` | 排除规则,限 `mode=URL` | `RegExp[]` | - `[allowClose]` | 允许关闭 | `boolean` | `true` `[showCurrent]` | 总是显示当前页 | `boolean` | `true` `[fixed]` | 是否固定 | `boolean` | `true` `(close)` | 关闭回调 | `EventEmitter` | - `(change)` | 切换时回调,接收的参数至少包含:`active`、`list` 两个参数 | `EventEmitter` | - 此项目参考自: ng-alain