将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
相关产品推荐
相关产品推荐

