【问题标题】:How to do page transitions with svelte/sapper如何使用 svelte/sapper 进行页面转换
【发布时间】:2019-12-19 04:56:24
【问题描述】:

我想在 Sapper 中实现一个简单的页面(路由)转换。例如,使用 Nuxt 可以轻松实现的目标。有谁知道如何使用 Sapper 实现这一点?

我已经使用 transition:fade 指令将我的页面内容包装到一个 div 中。这行得通。然而,两页同时转换,这意味着当一页转换出另一页时,另一页已经转换了。如果有人指出我正确的方向,那就太好了。谢谢!

【问题讨论】:

    标签: sapper svelte-transition


    【解决方案1】:

    首先让我说我不知道​​这是否是最有效的方法。这是我解决它的方法,它对我很有用。

    我首先制作了自己的“淡入淡出”过渡的自定义变体,并将其放在“components/pageFade.js”中

    import { sineOut } from "svelte/easing";
    
    let duration = 250;
    let delay = duration;
    
    let delayZero = 0;
    
    export const fadeIn = _ => ({
      duration,
      delay,
      easing: sineOut,
      css: t => `opacity: ${t}`
    });
    export const fadeOut = _ => ({
      duration,
      delay: delayZero,
      easing: sineOut,
      css: t => `opacity: ${t}`
    });
    
    1. delayZero 变量之所以存在,是因为由于某种原因它不会直接取 '0' 并且会中断。
    2. 持续时间变量是淡入淡出的长度,以毫秒为单位

    然后对于我想要进行此转换的所有文件,我执行了以下操作:

    <script>
      import { fadeIn, fadeOut } from "../components/pageFade";
    
      // All your other JS goes here
    </script>
    
    <style>
      /* Styles go here */
    </style>
    
    <main in:fadeIn out:fadeOut>
      <!-- All the normal HTML goes here -->
    </main>
    

    然后我会在几乎每一页上使用它作为模板,这看起来很多,但还不错。

    希望对您有所帮助,如果您有任何其他问题,请告诉我!

    最大

    【讨论】:

    • 如果我希望所有页面都使用相同的转换,是否需要为每个页面组件添加单独的转换,或者有没有办法将它添加到一个位置并为页面组件执行它?
    【解决方案2】:

    仅供参考@max-larsson,从您的代码中,fadeIn 被定义为一个不需要参数的函数,并返回一个具有duration 属性的对象,该属性等于此范围内的duration 变量的值。与delay 相同。注意easing定义为名称,值为sineOut

    如果您只是尝试将文字 0 放在 delay 所在的位置,这可能是您的问题。我看到您尝试制作delayZero,但使用它的方式可能与您的预期不同。你可能打算这样写:

    export const fadeOut = _ => ({
      duration,
      delay: 0,
      easing: sineOut,
      css: t => `opacity: ${t}`
    });
    

    当我尝试这个时,它对我来说效果很好。感谢您分享您的示例。

    【讨论】:

      【解决方案3】:

      如果您想在 _layout.svelte 中包含 transition 并且不需要在每条路线中都包含它们,这里是一种替代方法。

      这是一个简单的飞入/飞出顶部过渡

      <!-- src/component/PageTransitions.svelte -->
      <script>
        import { fly } from 'svelte/transition';
        export let refresh = '';
      </script>
      
      {#key refresh}
        <div
          in:fly="{{ y: -50, duration: 250, delay: 300 }}"
          out:fly="{{ y: -50, duration: 250 }}" 
          >
          <slot/>
        </div>
      {/key}
      

      这里是 Sapper layout 组件

      <!-- src/routes/_layout.svelte for Sapper -->
      
      <script>
        import { page } from '$app/stores'; // svelte@next
        import Nav from '../components/Nav';
        import PageTransitions from '../components/PageTransitions';
        export let segment;
      </script>
      
      <Nav {segment}/>
      
      <PageTransitions refresh={segment}>
        <slot/>
      </PageTransitions>
      

      这里是 SvelteKit (svelte@next) layout 组件

      <!-- src/routes/$layout.svelte for Svelte@next -->
      
      <script>
        import { page } from '$app/stores'; // svelte@next
        import Nav from '../components/Nav';
        import PageTransitions from '../components/PageTransitions';
      </script>
      
      <Nav segment={$page.path}/>
      
      <PageTransitions refresh={$page.path}>
        <slot/>
      </PageTransitions>
      

      为了完整起见,这里是一个简单的 Nav 组件

      <!-- src/component/Nav.svelte -->
      <script>
          export let segment;
      </script>
      
      <style>
        a {
          text-decoration: none;
        }
        .current {
          text-decoration: underline;
        }
      </style>
      <div>
        <a href="/" class='{segment === undefined ? "current" : ""}'>Home</a>
        <a href="/about" class='{segment === "about" ? "current" : ""}'>About</a>
      </div>
      

      注意事项: 我们通过创建 refresh 属性并使用 key 指令使组件具有反应性,这意味着当键更改时,svelte 会删除组件并添加一个新组件,从而触发转换。

      在布局组件中,我们将段(路由)作为refresh 属性传递,因此刷新键会随着路由的变化而变化。

      上面示例代码的Here is a demogithub repo

      【讨论】:

      • 重要的是要警告更改导航元素的 CSS z-index 以及 CSS 相对位置,以免与动画发生冲突。
      • 此外,对于 Sapper,您的代码是错误的/过时的。您需要以这种方式导入页面存储,而不是使用“import { page } from '$app/stores';”:sapper.svelte.dev/docs#Stores
      【解决方案4】:

      我猜自 @GiorgosK 回答以来 Svelte Kit 已经发生了变化,因为我无法使其与他回答中的代码一起使用。 但幸运的是,他的github repo 已经更新了解决方案,谢谢! page.path 属性多用于module context

      这是我的版本,没有页面转换的特定组件:

          <!-- src/route/__layout.svelte -->
          <script context="module">
              export const load = async ({ page }) => ({
                  props: {
                      key: page.path,
                  },
              });
          </script>
          
          <script>
              import { fly } from "svelte/transition";
              export let key;
          </script>
          
          <nav>
              <a href="/foo">foo</a>
              <a href="/bar">bar</a>
          </nav>
          
          {#key key}
              <div
                  in:fly={{ x: 50, duration: 2500 }}
                  out:fly={{ y: -50, duration: 2500 }}
              >
                  <slot />
              </div>
          {/key}
      

      也许@GiorgosK 可以分享一些关于这种变化的见解。

      【讨论】:

        猜你喜欢
        • 2019-10-18
        • 2013-04-28
        • 1970-01-01
        • 2022-06-21
        • 2019-11-13
        • 1970-01-01
        • 2020-05-18
        • 2020-09-15
        相关资源
        最近更新 更多