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

如何在Angular路由切换时为<router-outlet>添加淡入动画?

问题描述

我有如下HTML组件代码:

<section
  class="flex flex-col w-full h-[100vh] overflow-hidden animate__animated animate__fadeIn"
>
  <!-- 顶部导航栏固定在顶部,不会收缩 -->
  <app-top-navbar class="flex-shrink-0"></app-top-navbar>

  <!-- 包含侧边栏和动态内容的主区域 -->
  <div class="h-full flex overflow-hidden">
    <!-- 侧边导航栏宽度固定,不会伸缩 -->
    <app-side-navbar class="w-[10%] flex-shrink-0"></app-side-navbar>

    <!-- 可扩展且独立滚动的内容区域 -->
    <div class="w-full flex flex-col relative h-full overflow-y-auto">
      <p class="p-3 drop-shadow-md text-gray-800 font-semibold">
        {{ sectionTitle }}
      </p>
      <!-- 垂直可拉伸的居中路由容器 -->
      <div class="flex items-center justify-center h-full">
        <router-outlet></router-outlet>
      </div>

      <!-- 位于内容区域底部的导航组件 -->
      <app-overview-nav
        [back_router_link]="back_router_link"
        [next_router_link]="next_router_link"
      ></app-overview-nav>
    </div>
  </div>
</section>

当前页面加载时,整个section会执行animate__animated animate__fadeIn动画,但我希望下面这个容器:

<div class="flex items-center justify-center h-full">
  <router-outlet></router-outlet>
</div>

在每次路由切换时都触发animate__animated animate__fadeIn动画。我尝试直接给<router-outlet>添加这两个动画类,但没有效果。

解决方案

方法1:用Angular原生路由动画(推荐)

Angular自带路由切换动画支持,无需依赖外部类库:

  1. 在当前模块的@NgModule中导入动画模块:
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

@NgModule({
  imports: [
    // 其他已导入模块
    BrowserAnimationsModule
  ]
})
export class YourModule { }
  1. 在包裹路由的组件中定义动画逻辑:
import { trigger, transition, style, animate } from '@angular/animations';

@Component({
  // 组件元数据(selector、templateUrl等)
  animations: [
    trigger('routeFade', [
      // 组件进入时的淡入动画
      transition(':enter', [
        style({ opacity: 0 }),
        animate('300ms ease-in', style({ opacity: 1 }))
      ]),
      // 组件离开时的淡出动画(可选)
      transition(':leave', [
        animate('300ms ease-out', style({ opacity: 0 }))
      ])
    ])
  ]
})
export class YourComponent { }
  1. 修改模板,给路由容器绑定动画触发器:
<div class="flex items-center justify-center h-full" [@routeFade]>
  <router-outlet></router-outlet>
</div>

方法2:监听路由变化动态添加动画类

如果想用Animate.css的预设类,需要通过监听路由事件手动触发:

  1. 在组件中注入路由服务,监听路由切换完成事件:
import { Router, NavigationEnd } from '@angular/router';
import { ElementRef, ViewChild } from '@angular/core';
import { filter } from 'rxjs/operators';

@Component({
  // 组件元数据
})
export class YourComponent {
  @ViewChild('routeContainer') routeContainer!: ElementRef;

  constructor(private router: Router) {
    this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    ).subscribe(() => {
      // 先移除动画类避免重复触发异常
      this.routeContainer.nativeElement.classList.remove('animate__animated', 'animate__fadeIn');
      // 强制触发DOM重绘,确保动画能重新执行
      void this.routeContainer.nativeElement.offsetWidth;
      // 重新添加动画类触发淡入
      this.routeContainer.nativeElement.classList.add('animate__animated', 'animate__fadeIn');
    });
  }
}
  1. 给路由容器添加模板引用变量:
<div #routeContainer class="flex items-center justify-center h-full">
  <router-outlet></router-outlet>
</div>

为什么直接加在router-outlet上没用?

<router-outlet>是Angular的占位符元素,它本身不会被渲染到最终DOM中,真正显示的是路由对应的组件。所以动画类加在它身上不会生效,必须把动画作用在它的父容器或者路由组件本身上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 11:45:06