目录
- 1,实现路由切换
- [2,使用 CSSTransition 添加动画](#2,使用 CSSTransition 添加动画)
-
- [1,自定义动画组件 *TransitionRoute.jsx*](#1,自定义动画组件 TransitionRoute.jsx)
- 2,*App.jsx*
- 3,样式改动
- 3,注意点
通过一个例子来说明如何实现。
1,实现路由切换
基础样式
App.jsx
js
import { BrowserRouter as Router, Route, NavLink } from "react-router-dom";
import { Home, News, Goods } from "./page";
import "./App.css";
export default function App() {
return (
<div className="container">
<Router>
<div className="nav-box">
<NavLink to="/" exact>
首页
</NavLink>
<NavLink to="/news">新闻页</NavLink>
<NavLink to="/goods">商品页</NavLink>
</div>
<div className="page-box">
<Route path="/" exact component={Home}></Route>
<Route path="/news" component={News}></Route>
<Route path="/goods" component={Goods}></Route>
</div>
</Router>
</div>
);
}
App.css
css
.container {
margin: 0 auto;
width: 400px;
}
.nav-box {
background-color: lightblue;
line-height: 3;
text-align: center;
}
.nav-box a {
display: inline-block;
margin: 10px;
}
.nav-box a.active {
color: salmon;
}
.page-box {
height: 200px;
outline: 1px solid salmon;
}
page.jsx
js
import React from "react";
import "./page.css";
export function Home() {
return <div className="page home">Home</div>;
}
export function News() {
return <div className="page news">News</div>;
}
export function Goods() {
return <div className="page goods">Goods</div>;
}
page.css
css
.page {
height: 100%;
text-align: center;
}
.home {
background-color: lightblue;
}
.news {
background-color: lightgreen;
}
.goods {
background-color: lightyellow;
}
显示效果:
2,使用 CSSTransition 添加动画
CSSTransition 的使用参考 React@16.x(33)动画(上)
先看最终效果
- 可以看到路由页面(一开始)是重叠在一起的,所以需要使用绝对定位来实现。
- 动画过程中,对应的路由页面在动画开始前,应该是未加载的状态。同理,退出后应该是卸载状态。所以在
CSSTransition
组件上需要添加mountOnEnter
和unmountOnExit
完整代码:
1,自定义动画组件 TransitionRoute.jsx
match
属性未匹配时为 null
。
js
import React from "react";
import { Route } from "react-router-dom";
import { CSSTransition } from "react-transition-group";
import "animate.css";
export default function TransitionRoute(props) {
const { component: Comp, ...rest } = props;
return (
<Route {...rest}>
{({ match }) => {
return (
<CSSTransition
in={!!match}
timeout={500}
mountOnEnter
unmountOnExit
classNames={{
enterActive: "animate__fadeInRight",
exitActive: "animate__fadeOutLeft",
}}
>
<Comp></Comp>
</CSSTransition>
);
}}
</Route>
);
}
2,App.jsx
只需要将 Route
替换为 TransitionRoute
即可。
3,样式改动
App.css,父级元素添加相对定位。
css
.page-box {
position: relative;
}
page.jsx 。因为想使用 animate.css ,所以对进行动画的元素添加公共样式 animate__animated
js
import React from "react";
import "./page.css";
export function Home() {
return <div className="page animate__animated home">Home</div>;
}
export function News() {
return <div className="page animate__animated news">News</div>;
}
export function Goods() {
return <div className="page animate__animated goods">Goods</div>;
}
page.css,添加绝对定位。
css
.page {
position: absolute;
left: 0;
top: 0;
height: 100%;
width: 100%;
}
3,注意点
- 当不使用
Swtich
组件时,每个Route
组件都会加载,只是不显示而已。所以可实现切换路由的动画。 - 使用
Swtich
组件后,因为它只会加载匹配到的Route
组件,其他Route
组件并没有加载,所以无法完成退出进入动画。
在 React 的插件中可以检查下:
不使用 Switch
组件时,3个 Route
组件都会渲染,只是未匹配的不展示:
使用 Switch
后,只会渲染一个 Route
组件:
以上。