使用 Framer Motion 在 React 中实现页面转换

2025-06-10

使用 Framer Motion 在 React 中实现页面转换

在这个简短的教程中,我们将学习如何使用AnimatePresenceFramer Motion 提供的组件在 React 中的页面之间导航时创建我们自己的页面转换!

动画示例

我们将在本例中使用 React Router - 但同样的原理也适用于其他路由器实现(已经使用Next.js路由器进行了测试,并且没有任何问题!)

观看视频教程:

视频教程

您也可以从上面的链接下载源代码!

安装所需的软件包

首先,我们需要在 React 项目中安装所需的软件包。我们需要 React Router 用于导航,以及 Framer Motion 用于过渡行为。

yarn add react-router-dom framer-motion
Enter fullscreen mode Exit fullscreen mode

向我们的应用添加 BrowserRouter

ReactDOM.Render接下来,在调用的顶级组件中(对我来说是),我们希望将应用程序的容器包装在fromindex.tsx的实例中<Router>react-router

首先,我们将添加必要的导入index.tsx...

import { BrowserRouter as Router } from 'react-router-dom';
Enter fullscreen mode Exit fullscreen mode

然后,我们将把我们的顶级组件包装在这个路由器的实例中。

ReactDOM.render(
  <React.StrictMode>
    <Router> // <-- Adding this...
      <App />
    </Router> // <-- ...and this!
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

构建一个简单的开关

接下来,我们需要对顶级组件正下方的组件(在我们的示例中为App组件)进行一些更改。

在组件内部App,我们将为应用设置一个基本的路由系统。在本例中,我们只在两个简单页面之间导航,因此只需要一个<Switch>和两个<Route>组件即可。

因此让我们App.tsx先将它们导入到我们的文件中...

import { Switch, Route } from 'react-router-dom';
Enter fullscreen mode Exit fullscreen mode

接下来,我们将从App组件中返回一个简单的 switch。为了清晰起见,Page1组件Page2可以是任何有效的 React 组件。

const App = () => {
  return (
    <Switch>
      <Route path="/page1">
        <Page1 />
      </Route>
      <Route path="/page2">
        <Page2 />
      </Route>
    </Switch>
  );
};
Enter fullscreen mode Exit fullscreen mode

从 Framer Motion 添加 AnimatePresence

现在,是时候添加动画了!首先,我们将 Framer Motion 的组件包装进去<Switch><AnimatePresence>我们先导入它……

import { AnimatePresence } from 'framer-motion';
Enter fullscreen mode Exit fullscreen mode

然后,让我们将我们的应用程序包装在该新组件中。

const App = () => {
  return (
    <AnimatePresence exitBeforeEnter initial={false}>
      <Switch>
        <Route path="/page1">
          <Page1 />
        </Route>
        <Route path="/page2">
          <Page2 />
        </Route>
      </Switch>
    </AnimatePresence>
  );
};
Enter fullscreen mode Exit fullscreen mode

AnimatePresence仅当组件下方的子组件发生变化时,过渡效果才会生效AnimatePresence。在这种情况下,它就是我们的Switch组件。我们需要添加一些 props 来帮助AnimatePresence识别变化发生的时间。

再次,在中App.tsx,我们将从useLocation中导入钩子react-router

import { useLocation } from 'react-router-dom';
Enter fullscreen mode Exit fullscreen mode

现在,让我们将locationkey道具添加到我们的Switch

const App = () => {
  const location = useLocation();
  return (
    <AnimatePresence exitBeforeEnter initial={false}>
      <Switch location={location} key={location.pathname}>
        <Route path="/page1">
          <Page1 />
        </Route>
        <Route path="/page2">
          <Page2 />
        </Route>
      </Switch>
    </AnimatePresence>
  );
};
Enter fullscreen mode Exit fullscreen mode

将过渡效果参数添加到我们的页面组件中

好消息——我们的 App 组件已经完成了。现在,让我们给页面添加一些动画,一切就绪!

这是Page1我正在使用的组件。它非常简单——只是div一些简单的样式,然后链接Link到我们应用中的其他页面。

const Page1 = () => {
  return (
    <div style={{ ...styles.page, ...styles.page1 }}>
      <p style={styles.copy}>This is page 1</p>
      <Link style={{ ...styles.copy, ...styles.link }} to="/page2">
        Go to Page 2
      </Link>
    </div>
  );
};
Enter fullscreen mode Exit fullscreen mode

Page1为了在安装此组件时触发动画,我们需要将其包装到motion.divFramer Motion 提供的一个特殊组件中。那么,让我们导入它……

import { motion } from 'framer-motion';
Enter fullscreen mode Exit fullscreen mode

现在,我们将把我们的Page1组件包装在我们的新motion.div组件中,并提供一些道具来在安装时执行动画。

const Page1 = () => {
  return (
    <motion.div
      initial={{ scaleY: 0 }}
      animate={{ scaleY: 1 }}
      exit={{ scaleY: 0 }}
      transition={{ duration: 0.5 }}
    >
      <div style={{ ...styles.page, ...styles.page1 }}>
        <p style={styles.copy}>This is page 1</p>
        <Link style={{ ...styles.copy, ...styles.link }} to="/page2">
          Go to Page 2
        </Link>
      </div>
    </motion.div>
  );
};
Enter fullscreen mode Exit fullscreen mode

如您所见,我们motion.div也在这里向我们的组件添加了三个新道具。

  • initial - 这是动画开始组件的动画样式
  • animate - 这是动画结束组件的动画样式
  • exit - 这是动画结束组件的动画样式
  • transition - 过渡配置。在这里,我们指定持续时间(在本例中为 0.5 秒)。

有了这些道具,我们可以期待以下行为:

  • 道具首次安装时是不可见的(scaleY: 0
  • 然后,它将立即以动画形式在 0.5 秒内显示出来(scaleY: 1)。
  • 当它以动画形式呈现时,它会在从 DOM 中移除之前调整大小(scaleY: 0)。

最后,我们唯一需要做的事情就是使用相同的方法包装我们希望动画的其他页面组件。

我在两个页面之间制作动画(Page1Page2此示例中),因此我也需要包装Page2一个motion.div标签。

const Page2 = () => {
  return (
    <motion.div
      initial={{ scaleY: 0 }}
      animate={{ scaleY: 1 }}
      exit={{ scaleY: 0 }}
      transition={{ duration: 0.5 }}
    >
      <div style={{ ...styles.page, ...styles.page2 }}>
        <p style={styles.copy}>This is page 2</p>
        <Link style={{ ...styles.copy, ...styles.link }} to="/page1">
          Go to Page 1
        </Link>
      </div>
    </motion.div>
  );
};
Enter fullscreen mode Exit fullscreen mode

完成了!

就这样,我们完成了!我们已经成功在 React 中设置了页面导航时的精美动画。

现在,您应该已经掌握了自定义过渡样式所需的所有知识。每个页面还可以使用不同的过渡样式——一切皆有可能!

CodeSnap

CodeSnap 预览

如果你喜欢这门课程,我正在上传教程视频、课程、文章等等。如果你想了解更多内容,请考虑在CodeSnap.io上注册邮件列表。这鼓励我制作更多像这样的视频和文章🙏

感谢阅读!

鏂囩珷鏉ユ簮锛�https://dev.to/sam_piggott/using-framer-motion-to-make-page-transitions-in-react-5ma
PREV
⭐Angular 13 功能⭐如何更新到版本 13
NEXT
使用 ESLint 和 Prettier 为 Visual Studio Code 设置 TypeScript