react react-router V6 路由切换实现过渡动画

安装

npm install @types/react-transition-group react-transition-group --save
import { CSSTransition,TransitionGroup} from ‘react-transition-group’

目录结构

引入的话,是根据你想生成动画具体文件
我这边是在Layout,里面的Outlet加的动画,具体根据自己实际情况

  1. src>routers>index.tsx下新增路由配置文件
export const routers: RouteObject[] = [
    {
        path: '/',
        element: <AntLayout />,
        children: [
            {
                index: true,// 默认加载当前子项
                element: lazyLoad(<Home />)
            },
            {
                path: '/form/addform',
                element: lazyLoad(<AddForm />)
            },
            {
                path: '/form/watchform',
                element: lazyLoad(<WatchForm />)
            }
        ],
    },
    {
        path: '/login',
        element: lazyLoad(<Login />)
    }
]

启用懒加载

const lazyLoad = (children: ReactNode): ReactNode => {
    return (
        <Suspense >
            {children}
        </Suspense>
    )
}
  1. App.tsx 引入配置好的路由
import { useRoutes } from 'react-router-dom';
import { routers } from './routers';
import React from 'react';
import './App.scss'

const App: React.FC = () => {
  return useRoutes(routers)
};

export default App;
  1. 入口文件index.tsx 选择哈希还是history模式
    这里注意一点,react严格模式在使用过渡动画会抛错,这里就把严格模式删了
import ReactDOM from 'react-dom/client';
import { BrowserRouter as Router } from 'react-router-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
    <Router>
      <App />
    </Router>
);

reportWebVitals();
  1. 最后是在顶级文件AntLayout.tsx中引入过渡动画插件
    我这里是用的ant-design Layout Menu组件,官网有示例代码直接copy
    过渡动画只需要加在路由出口位置,目前v6的Outlet同vue router-view相同用法。

SwitchTransition搭配CSSTransition使用
SwitchTransition模式有两种out-in | in-out

<Content style={{ padding: 24, margin: 0, flexGrow: 1, overflow: 'auto' }}>
     <Breadcrumb separator=">" style={{ fontSize: 14, marginBottom: 20 }}>{finalCrumbItems}</Breadcrumb>
     <SwitchTransition mode="out-in">
         <CSSTransition key={location.key} timeout={300} classNames="fade" nodeRef={null}>
             <Outlet />
         </CSSTransition>
     </SwitchTransition>
</Content>

完整一点代码

const AntLayout: React.FC = () => {
    const [collapsed, setCollapsed] = useState(false)
    const navigate = useNavigate()
    const location = useLocation()
    const pathSnippets = location.pathname.split('/').filter(i => i)
    const breadCrumbItems = pathSnippets.map((_, index) => {
        const url = `/${pathSnippets.slice(0, index + 1).join('/')}`
        return (
            <Breadcrumb.Item key={url}>
                <Link to={url}>{pathMaps[url]}</Link>
            </Breadcrumb.Item>
        )
    })
    const finalCrumbItems = [
        <Breadcrumb.Item key="/">
            <Link to="/">首页</Link>
        </Breadcrumb.Item>
    ].concat(breadCrumbItems)
    return (
        <Layout style={{ minHeight: '100vh' }}>
            <Sider
                collapsible
                collapsed={collapsed}
                onCollapse={value => setCollapsed(value)}>
                <div className="logo"></div>
                <Menu
                    theme="dark"
                    defaultSelectedKeys={['1']}
                    mode="inline"
                    onClick={handleMenuClick}
                    onSelect={({ key }) => navigate(key)}
                    items={items} />
            </Sider>
            <Layout style={{ display: 'flex', flexDirection: 'column', height: '100vh' }}>
                <Header>
                    欢迎来到缅北诈骗系统
                </Header>
                <Content style={{ padding: 24, margin: 0, flexGrow: 1, overflow: 'auto' }}>
                    <Breadcrumb separator=">" style={{ fontSize: 14, marginBottom: 20 }}>{finalCrumbItems}</Breadcrumb>
                    <SwitchTransition mode="out-in">
                        <CSSTransition key={location.key} timeout={300} classNames="fade" nodeRef={null}>
                            <Outlet />
                        </CSSTransition>
                    </SwitchTransition>
                </Content>
                <Footer style={{ textAlign: 'center' }}>
                    Ant Design @2018 Created by Ant UED
                </Footer>
            </Layout>
        </Layout>
    )
}

过渡动画的样式

.fade-exit {
  opacity: 0;
  transform: translateX(50px);
}

.fade-exit-active {
  opacity: 1;
  transform: translateX(0%);
}

.fade-enter-active,
.fade-exit-active {
  transition: all 300ms;
}

参考官网样式: 过渡动画.

效果

transform

总结

目前只是把这个动画简单实现下,仅供学习参考,还有些问题比如出现滚动条还是没解决。

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
React Router是一个用于建立SPA应用程序的库,它提供了一种将应用程序状态与URL同步的方式。React Router v6React Router的最新版本,它引入了一些新的概念和语法。 下面是使用React Router v6搭建路由的步骤: 1. 安装React Router v6 使用npm或者yarn安装React Router v6: ``` npm install react-router-dom@next ``` 2. 创建路由 在应用程序的入口文件中,使用BrowserRouter创建一个路由: ```jsx import { BrowserRouter } from 'react-router-dom'; ReactDOM.render( <BrowserRouter> <App /> </BrowserRouter>, document.getElementById('root') ); ``` 3. 定义路由 使用Route组件定义路由。Route组件的path属性指定URL的路径,component属性指定该路径对应的组件: ```jsx import { Route } from 'react-router-dom'; function App() { return ( <div> <Route path="/" component={Home} /> <Route path="/about" component={About} /> </div> ); } ``` 在上面的例子中,当URL路径为“/”时,渲染Home组件;当URL路径为“/about”时,渲染About组件。 4. 处理404页面 使用Route组件的exact属性确保路由匹配完全相等的路径。这样可以避免在匹配“/”路径时同时匹配到所有其他路径。 使用Route组件的path属性指定“*”路径,即匹配所有路径的路径。将这个Route组件放在所有其他Route组件的下面,就可以为未匹配到任何路径的URL显示404页面: ```jsx import { Route, Routes } from 'react-router-dom'; function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="*" element={<NotFound />} /> </Routes> </div> ); } ``` 在上面的例子中,当URL路径为任何未匹配到的路径时,渲染NotFound组件。 5. 嵌套路由 使用Routes组件嵌套Route组件,可以创建嵌套路由。在嵌套路由中,父级Route组件的path属性包含所有子级Route组件的path属性的前缀。 ```jsx import { Route, Routes } from 'react-router-dom'; function App() { return ( <div> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />}> <Route path="team" element={<Team />} /> <Route path="history" element={<History />} /> </Route> <Route path="*" element={<NotFound />} /> </Routes> </div> ); } ``` 在上面的例子中,当URL路径为“/about/team”时,渲染Team组件;当URL路径为“/about/history”时,渲染History组件。 React Router v6引入了一些新的语法,例如使用Routes组件代替Router组件,使用element属性代替component属性等。这些语法的目的是让React Router更加简洁易用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值