You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Angular 5 Material Sidenav封装为独立组件以实现多页面复用

嘿,刚学Angular Material的时候我也纠结过这个问题!把侧边栏封装成独立组件复用太有必要了,我来一步步带你实现:

1. 先创建独立的侧边栏组件

用Angular CLI快速生成组件就行,选个合适的路径(比如放在shared目录下,方便全局复用):

ng generate component shared/sidenav
2. 改造侧边栏组件的模板与逻辑

把原来代码里的<mat-drawer>部分移到新组件的模板里,还要把抽屉实例暴露给父组件,方便控制开关。

sidenav.component.html:

<mat-drawer #drawer class="sidebar-sidenav" mode="side">
  <!-- 这里放你的侧边栏内容,比如导航链接或者之前的<app-sidenav>组件 -->
  <app-sidenav-links></app-sidenav-links> <!-- 替换成你实际的侧边栏内容 -->
</mat-drawer>

sidenav.component.ts:

import { Component, ViewChild } from '@angular/core';
import { MatDrawer } from '@angular/material/sidenav';

@Component({
  selector: 'app-shared-sidenav',
  templateUrl: './sidenav.component.html',
  styleUrls: ['./sidenav.component.scss']
})
export class SharedSidenavComponent {
  // 暴露抽屉实例,供父组件调用
  @ViewChild('drawer') drawer!: MatDrawer;

  // 可以封装常用的控制方法,比如切换抽屉
  toggleDrawer() {
    this.drawer.toggle();
  }
}
3. 封装通用布局容器(推荐)

为了让侧边栏和页面内容的布局更灵活,建议再做一个布局组件,把<mat-drawer-container>和插槽结合起来,这样页面内容可以动态插入:

layout.component.html:

<mat-drawer-container class="sidebar-container" autosize>
  <!-- 引入刚才的侧边栏组件 -->
  <app-shared-sidenav></app-shared-sidenav>
  <!-- 页面内容插槽,父组件的内容会插到这里 -->
  <div class="sidebar-sidenav-content">
    <ng-content></ng-content>
  </div>
</mat-drawer-container>

layout.component.scss:

.sidebar-container {
  height: 100vh; /* 占满视口高度 */
}

.sidebar-sidenav {
  width: 250px; /* 侧边栏宽度,按需调整 */
}

.sidebar-sidenav-content {
  padding: 2rem;
  width: 100%;
}
4. 在任意页面组件中复用

现在你可以在任何页面里直接用这个布局组件了,比如首页:

home.component.html:

<app-layout>
  <!-- 这里放你的首页内容 -->
  <h1>欢迎来到我的首页</h1>
  <p>侧边栏已经自动加载,不用重复写代码啦!</p>
  <button (click)="toggleSidenav()">切换侧边栏</button>
</app-layout>

如果需要在页面里控制侧边栏,比如点击按钮切换,只需要在页面组件里获取侧边栏实例:

home.component.ts:

import { Component, ViewChild } from '@angular/core';
import { SharedSidenavComponent } from '../shared/sidenav/sidenav.component';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent {
  @ViewChild(SharedSidenavComponent) sidenavComponent!: SharedSidenavComponent;

  toggleSidenav() {
    this.sidenavComponent.toggleDrawer();
  }
}
小提醒
  • 别忘了在你的模块(比如AppModule或者feature模块)里导入MatSidenavModule,还有你创建的这些组件哦!
  • 如果不同页面的侧边栏内容需要变化,可以用@Input()传递数据,或者给侧边栏加个<ng-content>插槽。
  • 样式尽量写在组件的scss文件里,避免全局样式冲突。

这样封装完,所有页面都能轻松复用同一个侧边栏啦,省了超多重复代码!

内容的提问来源于stack exchange,提问作者usp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:03:22