7

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

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

4

4 回答 4

11

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

我首先制作了自己的“淡入淡出”过渡的自定义变体,并将其放在“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>

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

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

最大限度

于 2019-08-17T19:20:10.080 回答
6

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

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

<!-- 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布局组件

<!-- 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)布局组件

<!-- 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>

注意: 我们通过创建一个refreshprop 和 usingkey指令来使组件具有响应性,这意味着当键更改时,svelte 会删除组件并添加一个新组件,从而触发转换。

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

这是上面示例代码和github repo的演示

于 2020-11-20T20:02:54.733 回答
3

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

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

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

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

于 2020-01-01T06:43:29.863 回答
0

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

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

    <!-- 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 可以分享一些关于这种变化的见解。

于 2021-08-11T11:01:47.960 回答