面试题答案
一键面试Angular的变化检测策略
- Default(默认)策略
- 工作原理:Angular会在每个事件循环周期(如DOM事件、XHR响应、setTimeout等)结束时,从根组件开始自上而下检查整个组件树。它会检查组件的输入属性、模板表达式以及指令绑定等是否发生变化。如果检测到变化,Angular会更新DOM。
- OnPush策略
- 工作原理:当组件使用OnPush策略时,Angular只会在以下几种情况下检查该组件及其子组件:
- 输入属性(@Input())引用发生变化。例如,传递给组件的对象引用改变了,而不仅仅是对象内部属性改变。
- 组件接收到事件(如click、submit等DOM事件,或自定义事件)。
- 可观察对象(Observable)发出新值。但仅当Observable是使用rxjs的Subject、BehaviorSubject、ReplaySubject等创建,并且在组件的构造函数或ngOnInit中订阅时才会触发变化检测。
- 工作原理:当组件使用OnPush策略时,Angular只会在以下几种情况下检查该组件及其子组件:
在大型项目中优化变化检测机制提升性能
- 适合使用OnPush策略的场景
- 纯展示组件:这类组件仅根据输入数据展示信息,不依赖外部状态变化,且输入数据不频繁变化。例如,显示用户基本信息的卡片组件,只要用户信息不更新,组件就无需重新检查变化。
- 子组件树独立且稳定:当子组件树的状态主要由自身管理,且与父组件交互较少,仅在特定输入变化时才需要更新。比如,分页组件,只有当当前页码或总页数等输入属性变化时才需要更新。
- 正确使用OnPush策略
- 确保输入属性不可变:由于OnPush策略依赖输入属性引用变化,所以传递给组件的对象或数组应尽量保持不可变。例如,不要直接修改传递给组件的数组,而是创建一个新数组并传递。
- 合理处理事件:在组件内部处理事件时,确保事件处理逻辑不会意外触发不必要的变化检测。如果事件处理导致组件状态变化,应确保这种变化是预期的,并且不会引起过多不必要的重新渲染。
- 正确处理可观察对象:当组件依赖可观察对象时,确保可观察对象的订阅逻辑正确。如果在组件的生命周期钩子(如ngOnInit)之外订阅可观察对象,可能无法触发OnPush策略下的变化检测。此外,使用shareReplay等操作符时要谨慎,避免多次订阅导致数据不一致问题。