【问题标题】:Pagetransition before next page in NextjsNextjs中下一页之前的页面转换
【发布时间】:2021-01-31 10:41:02
【问题描述】:

是否有任何方法可以归档符合以下要求的页面过渡:

  • 我想在页面更改时显示页面转换
  • 页面转换应在下一页加载/显示之前完成
  • 页面转换应该运行 X 秒
  • 页面过渡是放在_app.js中的一个组件

目前,我以一种令人毛骨悚然的方式做到这一点。 在 NuxtJS 中,可以通过 Javascript Hooks 将其归档。 https://nuxtjs.org/docs/2.x/components-glossary/pages-transition

感谢您的帮助:)

【问题讨论】:

  • Next.js 没有像 Nuxt.js 那样的内置简单方法。您可以查看可以帮助解决此问题的外部库,例如 framer-motionreact-spring)。
  • 这与动画本身无关。我知道这两个库。它更多的是对路由的处理。那么就可以在进入下一页之前运行动画了。目前,我使用一个 Link 组件来运行动画,然后推送新的路线。我只是想知道是否有像nuxt这样的好方法。谢谢你:)
  • 在这种情况下也许值得看看next/router's events。甚至可以在_app 中收听这些。
  • 我做了,但没有符合我要求的事件,或者我没有正确使用它。过渡必须在新页面进入之前准备好。在 routeChangeStart 的情况下,您会看到动画运行时内容发生变化。

标签: reactjs next.js


【解决方案1】:

您可以挂钩到 Next.js 路由器事件,但您不能设置转换需要多长时间。

例如如果您希望转换为 3 秒:

  • 如果 Next.js 转换需要 1 秒,您可以等待 2 秒,但是
  • 如果 Next.js 转换需要 4 秒,您将无能为力。

而且您无法确定 Next.js 转换需要多长时间。

自定义“路由”

无论如何,如果您依赖 Next.js 过渡从不花费比动画更多的时间,那么您将不得不以某种方式“存储”旧页面视图,并在动画运行时显示它而不是新页面。

从 Next.js 的角度来看,应该会显示新页面。我认为这不适用于 Next.js 路由,我猜你必须自己进行“路由”(根据 url 显示内容)。例如。将您的应用程序设计为始终同时具有两个页面,一个显示,一个隐藏并且可能正在加载。然后,您可以随时在这两个页面之间切换。

你可能想看看实验功能React "Suspense"(我不知道,我没用过)。

路由前等待

如果你想在过渡开始前等待一段时间,你可以这样做:

const startAnimation = () => {
    return new Promise( ( resolve, reject ) => {
        console.log('...animate...');
        
        setTimeout( resolve, 3000 ); // <-- replace this line with your animation, and call resolve() when finished
    } );
};

const routerWrapper = {
    push: ( url ) => {
        startAnimation().then( () => {
            console.log('Next.js routing starts...');
            Router.push( url );
        })
    }
};

// ...

routerWrapper.push( newUrl ); // <-- this instead of Router.push( newUrl )

路由完成时停止动画

如果你想在调用Route.push()时启动动画,并在Next.js过渡完成时停止动画,你可以使用Next.js routerevents,例如:

export default function App( props: AppProps ) {
    const { Component, pageProps } = props;
    const router = useRouter()

    useEffect(() => {
        const routeChangeStart = (url, { shallow }) => {
            console.log('start animation');
        };

        const routeChangeComplete = (url, { shallow }) => {
            console.log('stop animation');
        };

        router.events.on('routeChangeStart', routeChangeStart);
        router.events.on('routeChangeComplete', routeChangeComplete);

        return () => {
            router.events.off('routeChangeStart', routeChangeStart);
            router.events.off('routeChangeComplete', routeChangeComplete);
        }
    }, [])

    // --
    return (
        <Component { ...pageProps } />
    );
}

【讨论】:

    【解决方案2】:

    我还没有亲自做过,但看起来你可以用 Framer Motion 做这样的事情。

    在您的主 App 组件中从路由器解构 props

    function App({ Component, pageProps, router }) {
    

    然后,您可以使用 Framer Motion 中的 AnimatePresence 组件为路线加载和退出设置动画。您说您熟悉 cmets 中的库,所以我不会谈论该组件,但这是您添加到 AnimatePresence 组件中的 motion.div 的内容

    <motion.div key={router.route}>
    

    下面我将链接一篇关于如何做的好文章和一个好的回购作为示例。这些都不是我写的,但它们非常有用且具有描述性。

    https://www.freecodecamp.org/news/how-to-add-interactive-animations-and-page-transitions-to-a-next-js-web-app-with-framer-motion/#step-3-adding-page-transitions-with-framer-motion-to-a-next-js-app

    https://github.com/colbyfayock/my-rick-and-morty-wiki/commit/3c1455370f750ff86b75a3b3edc446ebe553bf5b

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-04
      相关资源
      最近更新 更多