angular2中的路由转场动效
1、为什么有的人路由转动效离场动效不生效?
自己研究发现是加动效的位置放错了 如下:
<---! animate-state.component.html --> <div style="background-color: antiquewhite;width: 100vw" [@trigger] id="f"> style="background-color: antiquewhite;width: 100%;height: 100px; </div>
//有的人可能会在组件内容的最顶层元素 加一个动效。以为这样能达到路由转场的效果,其实不然,因为组件本身才是这个组件的根元素。当通过路由转场时,
//离场的根元素瞬间就隐藏了,以有其组件里面的内容不管加什么动效也无用,有动效,元素隐藏了也看不到啊!
// 如上面的的html 模块名为:selector: 'app-animate-state',那么<app-animate-state></app-animate-state>是根元素,动画应该加在这样面才会有转场效果,而不是上面的组件内容最顶层元素
2、解决放法
因为路由你是没法写代表一个路由内容<app-animate-state></app-animate-state>这个标签元素的。
那么怎么做了?如下
用 @HostBinding()绑定根元素,加上动效。
/路由切换动效如下 //animate-state.component.html <div style="background-color: antiquewhite;width: 100vw"> style="background-color: antiquewhite;width: 100%;height: 100px; </div> //animate-state.component.ts import {Component, HostBinding, OnInit} from '@angular/core'; import {trigger2} from "../animation/trigger"; @Component({ selector: 'app-animate-state', templateUrl: './animate-state.component.html', styleUrls: ['./animate-state.component.css'], animations: [trigger2] }) export class AnimateStateComponent implements OnInit { constructor() { } @HostBinding('@trigger2') trigger2 = ""; ngOnInit() { } } //animate-trigger.component.html <div style="background-color: red;width: 100vw"> [@heroState] = 'name' </div> //animate-trigger.component.ts import {Component, HostBinding, OnInit} from '@angular/core'; import {trigger1, trigger2} from "../animation/trigger"; @Component({ selector: 'app-animate-trigger', templateUrl: './animate-trigger.component.html', styleUrls: ['./animate-trigger.component.css'], animations: [trigger1, trigger2] }) export class AnimateTriggerComponent implements OnInit { constructor() { } @HostBinding('@trigger2') trigger2 = ""; ngOnInit() { } } //app.module.ts const appRoutes: Routes = [ { path: 'trigger', component: AnimateTriggerComponent }, { path: 'state', component: AnimateStateComponent }, { path: '', redirectTo: '/trigger', pathMatch: 'full' }, { path: '**', component: AnimateTriggerComponent } ]; //app.component.html <a routerLink="/trigger" routerLinkActive="active">trigger</a> <a routerLink="/state" routerLinkActive="active">state</a> <div id="app"> <router-outlet></router-outlet> </div> //trigger.ts 动效 export const trigger2 = trigger('trigger2', [ transition('* => void', [style({opacity: 1,position: 'absolute'}),animate(1000,style({opacity: 0}))]), transition('void => *', [style({opacity: 0,position: 'absolute'}),animate(2000,style({opacity: 1}))]) ]);
3、可是这样做的话,每个路由都要这样加,会显的很繁琐,在重复,有办法一次性全加上吗? 当然是有 如下: 用到动效里的query特性函数和路由中的NavigationEnd属性 代码如下
//animate-state.component.html <div style="background-color: antiquewhite;width: 100vw"> style="background-color: antiquewhite;width: 100%;height: 100px; </div> //animate-state.component.ts import {Component, HostBinding, OnInit} from '@angular/core'; @Component({ selector: 'app-animate-state', templateUrl: './animate-state.component.html', styleUrls: ['./animate-state.component.css'], }) export class AnimateStateComponent implements OnInit { constructor() { } ngOnInit() { } } //animate-trigger.component.html <div style="background-color: red;width: 100vw"> [@heroState] = 'name' </div> //animate-trigger.component.ts import {Component, HostBinding, OnInit} from '@angular/core'; @Component({ selector: 'app-animate-trigger', templateUrl: './animate-trigger.component.html', styleUrls: ['./animate-trigger.component.css'], }) export class AnimateTriggerComponent implements OnInit { constructor() { } ngOnInit() { } } //trigger.ts
import {
trigger,
state,
style,
animate,
transition, query, group
} from '@angular/animations';
import {AnimationEntryMetadata} from "@angular/core";
export const routeAnimation1: AnimationEntryMetadata = trigger('routeAnimation1', [ transition('* => *', group([ query(':leave', animate('.5s',
style({opacity: 0,position: 'absolute'})), { optional: true }), query(':enter', [style({opacity: 0,position: 'absolute'}),
animate('.5s', style({ opacity: 1}))],{ optional: true }) ]) ) ]);
//app.module.ts
const appRoutes: Routes = [ { path: 'trigger', component: AnimateTriggerComponent },
{ path: 'state', component: AnimateStateComponent }, { path: '', redirectTo: '/trigger', pathMatch: 'full' } ];
//app.component.html
<a routerLink="/trigger" routerLinkActive="active">trigger</a>
<a routerLink="/state" routerLinkActive="active">state</a>
<div id="app" [@routeAnimation1]="routerStateCode">
<router-outlet>
</router-outlet>
</div>
//app.component.ts
import { Component } from '@angular/core'; import {NavigationEnd, Router} from "@angular/router";
import { routeAnimation1} from "./animation/trigger";
@Component({ selector: 'app-root', templateUrl:
'./app.component.html', styleUrls: ['./app.component.css'],
animations: [routeAnimation1] })
export class AppComponent {
routerState:boolean = true;
routerStateCode:string = 'active';
constructor(private router:Router)
{ this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
// 每次路由跳转改变状态
console.log(NavigationEnd,event)
this.routerState = !this.routerState;
this.routerStateCode = this.routerState ? 'active' : 'inactive'; } }); } }
有问题,欢迎留言。。。
“我相当乐意花一天的时间通过编程把一个任务实现自动化,除非这个任务手动只需要10秒钟就能完成”