Angular CDK 简介

Angular Component Dev Kit (CDK) 是 Angular 官方提供的工具库,用于构建高性能、可复用的组件。其响应式工具和自适应布局模块(@angular/cdk/layout)简化了响应式设计实现,无需直接依赖 CSS 媒体查询。

核心模块:@angular/cdk/layout

该模块提供基于 TypeScript 的响应式断点检测,支持动态布局调整。主要包含以下功能:

  • 断点观察器:监听视口变化并触发响应事件。
  • 响应式工具服务:提供当前屏幕尺寸状态的实时数据。

安装与基础配置

在项目中安装 Angular CDK:

ng add @angular/cdk

导入模块:

import { LayoutModule } from '@angular/cdk/layout';

@NgModule({
  imports: [LayoutModule]
})
export class AppModule {}

使用 BreakpointObserver 服务

BreakpointObserver 是核心服务,用于检测预定义的断点(如手机、平板、桌面)。

监听断点变化示例:

import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';

constructor(private breakpointObserver: BreakpointObserver) {
  breakpointObserver.observe([
    Breakpoints.Handset,
    Breakpoints.Tablet,
    Breakpoints.Web
  ]).subscribe(result => {
    this.isHandset = result.matches;
  });
}

预定义断点常量

Angular CDK 提供以下常用断点常量:

  • Breakpoints.Handset: 手机竖屏(最大宽度 599px)。
  • Breakpoints.Tablet: 平板竖屏(600px - 839px)。
  • Breakpoints.Web: 桌面或横屏(最小宽度 840px)。
  • Breakpoints.HandsetLandscape: 手机横屏(最大高度 599px)。

自定义断点

支持自定义断点规则:

const customBreakpoints = [
  '(max-width: 500px)',
  '(min-width: 501px) and (max-width: 1000px)'
];

breakpointObserver.observe(customBreakpoints).subscribe(result => {
  this.isSmallScreen = result.breakpoints[customBreakpoints[0]];
});

响应式布局实践

结合 *ngIfngClass 动态调整 UI:

<div *ngIf="isHandset$ | async; then mobileView else desktopView"></div>

<ng-template #mobileView>
  <app-mobile-nav></app-mobile-nav>
</ng-template>

<ng-template #desktopView>
  <app-desktop-nav></app-desktop-nav>
</ng-template>

性能优化建议

  • 取消订阅:避免内存泄漏,在组件销毁时取消订阅:

    private destroy$ = new Subject<void>();
    
    ngOnInit() {
      this.breakpointObserver.observe(...)
        .pipe(takeUntil(this.destroy$))
        .subscribe(...);
    }
    
    ngOnDestroy() {
      this.destroy$.next();
      this.destroy$.complete();
    }
    

  • 防抖处理:频繁触发时限制回调执行频率:

    import { debounceTime } from 'rxjs/operators';
    
    breakpointObserver.observe(...)
      .pipe(debounceTime(100))
      .subscribe(...);
    

与 Angular Flex Layout 对比

特性 Angular CDK Layout Angular Flex Layout
依赖 纯 TypeScript 需要 CSS 弹性盒子支持
性能 轻量级,逻辑层处理 依赖浏览器渲染
适用场景 复杂逻辑条件响应 简单网格/弹性布局

常见问题解决方案

问题1:断点检测不生效

  • 确认 BreakpointObserver 已正确注入。
  • 检查断点字符串格式是否符合 CSS 媒体查询语法。

问题2:多端样式冲突

  • 使用 BreakpointObserver.isMatched() 方法精确控制状态:
    const isTablet = this.breakpointObserver.isMatched(Breakpoints.Tablet);
    

高级应用:自定义响应式指令

创建指令实现条件渲染:

@Directive({ selector: '[ifViewportSize]' })
export class IfViewportSizeDirective {
  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private breakpointObserver: BreakpointObserver
  ) {}

  @Input() set ifViewportSize(breakpoint: string) {
    this.breakpointObserver.observe(breakpoint)
      .subscribe(result => {
        result.matches 
          ? this.viewContainer.createEmbeddedView(this.templateRef)
          : this.viewContainer.clear();
      });
  }
}

使用方式:

<div *ifViewportSize="'(min-width: 600px)'">仅桌面可见</div>

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐