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

如何在Angular 5项目中引入Materialize并初始化侧边栏等组件?

在Angular生产环境中使用Materialize CSS的最佳实践

嘿,我来分享下在Angular生产环境中用Materialize CSS的最佳方案,刚好之前我也碰到过组件里没法在index.html初始化侧边栏的问题,下面分两部分给你说清楚:

一、推荐的引入方式:通过npm安装(而非CDN)

生产环境下,用npm管理Materialize依赖比CDN靠谱太多了——版本可控、方便构建优化,还能避免外部CDN挂掉影响你的项目。具体步骤很简单:

  1. 先安装Materialize和它的依赖(jQuery和Popper.js,Materialize底层依赖这俩)
npm install materialize-css jquery popper.js
  1. 配置Angular项目
    • 全局引入的话,直接改angular.json:找到build -> options里的styles和scripts数组,把Materialize的样式和脚本加进去:
      "styles": [
        "node_modules/materialize-css/dist/css/materialize.min.css",
        "src/styles.css"
      ],
      "scripts": [
        "node_modules/jquery/dist/jquery.min.js",
        "node_modules/popper.js/dist/umd/popper.min.js",
        "node_modules/materialize-css/dist/js/materialize.min.js"
      ]
      
    • 要是你想按需在组件里导入样式,也可以在组件的CSS文件里加这句:
      @import "~materialize-css/dist/css/materialize.min.css";
      

二、Materialize组件的正确姿势:在组件生命周期里初始化

因为Angular组件有自己的渲染周期,你在index.html的script里初始化的话,导航栏组件的DOM还没渲染出来,肯定没用。所以得在组件的ngAfterViewInit钩子里面做——这个钩子触发的时候,组件的视图已经完全渲染好了,DOM元素都能拿到。

1. 侧边栏(Sidenav)初始化

方式一:原生DOM查询(简单场景够用)

在你的导航栏组件(比如navbar.component.ts)里这么写:

import { Component, AfterViewInit } from '@angular/core';
declare var M: any; // 声明全局的M对象,避免TypeScript报错

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements AfterViewInit {

  ngAfterViewInit(): void {
    // 找到侧边栏元素,初始化
    const elem = document.querySelector('.sidenav');
    const instance = M.Sidenav.init(elem, {
      // 这里可以加配置项,比如侧边栏从哪边滑出来、动画时长
      edge: 'left',
      inDuration: 300
    });
  }
}

方式二:用Angular的ViewChild(更符合Angular风格)

这种方式不用全局查DOM,更可控,推荐用:

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
declare var M: any;

@Component({
  selector: 'app-navbar',
  template: `
    <ul class="sidenav" #sidenavRef>
      <!-- 侧边栏的菜单内容 -->
      <li><a href="#!">首页</a></li>
      <li><a href="#!">关于我们</a></li>
    </ul>
    <!-- 触发按钮 -->
    <a href="#" data-target="sidenavRef" class="sidenav-trigger"><i class="material-icons">menu</i></a>
  `
})
export class NavbarComponent implements AfterViewInit {
  @ViewChild('sidenavRef') sidenavRef!: ElementRef;

  ngAfterViewInit(): void {
    // 用ViewChild拿到的元素初始化
    const instance = M.Sidenav.init(this.sidenavRef.nativeElement, {
      edge: 'left'
    });
    // 要是以后需要操作这个实例(比如手动打开/关闭),可以把instance存成组件属性
    // this.sidenavInstance = instance;
  }
}

2. 轮播(Carousel)初始化

和侧边栏思路一样,在包含轮播的组件里用ngAfterViewInit:

import { Component, AfterViewInit, ViewChild, ElementRef } from '@angular/core';
declare var M: any;

@Component({
  selector: 'app-carousel',
  template: `
    <div class="carousel" #carouselRef>
      <a class="carousel-item" href="#one!"><img src="assets/image1.jpg"></a>
      <a class="carousel-item" href="#two!"><img src="assets/image2.jpg"></a>
      <a class="carousel-item" href="#three!"><img src="assets/image3.jpg"></a>
    </div>
  `
})
export class CarouselComponent implements AfterViewInit {
  @ViewChild('carouselRef') carouselRef!: ElementRef;

  ngAfterViewInit(): void {
    const instance = M.Carousel.init(this.carouselRef.nativeElement, {
      // 配置项示例:全屏显示、显示指示器、切换动画时长
      fullWidth: true,
      indicators: true,
      duration: 200
    });
  }
}

额外小技巧

  • 要是遇到TypeScript报类型错误,直接装个Materialize的类型定义包就行:
    npm install @types/materialize-css --save-dev
    
    装完之后就不用写declare var M: any;了,直接导入:
    import * as M from 'materialize-css';
    
  • 生产构建的时候,Angular的打包工具会自动优化这些依赖,不用担心体积太大的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:30:36