Как сделать переходы страниц с svelte/sapper
Я хочу реализовать простой переход страницы (маршрута) в Sapper. Что-то, что легко достижимо, например, с помощью Nuxt. У кого-нибудь есть идеи, как это реализовать с помощью Sapper?
Я уже обернул содержимое своей страницы в div с помощью директивы перехода: исчезать. Это работает. Тем не менее, две страницы переходят в одно и то же время, то есть, когда одна страница выходит, а другая уже переходит. Было бы здорово, если бы кто-то указал мне правильное направление. Спасибо!
4 ответа
Позвольте мне начать с того, что я не знаю, является ли это наиболее эффективным способом сделать это. Это способ, которым я решил это, и это прекрасно работает для меня.
Сначала я сделал свой собственный вариант перехода 'fade' и поместил его в '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,
delayZero,
easing: sineOut,
css: t => `opacity: ${t}`
});
- Существует переменная delayZero, потому что по какой-то причине она не будет принимать '0' напрямую и будет прерываться.
- Переменная длительности - это длина замирания в миллисекундах.
Затем для всех файлов, которые я хотел включить, я сделал следующее:
<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>
Затем я бы использовал это в качестве шаблона почти на каждой странице, что кажется довольно большим, но не так уж плохо.
Надеюсь, это поможет, и дайте мне знать, если у вас есть другие вопросы!
Максимум
Если вы хотите включить переход в _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}
А вот компонент макета
<!-- src/routes/$layout.svelte for Svelte@next -->
<!-- src/routes/_layout.svelte for Sapper -->
<script>
import Nav from '../components/Nav';
import PageTransitions from '../components/PageTransitions';
export let segment;
</script>
<Nav {segment}/>
<PageTransitions refresh={segment}>
<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
prop и, следовательно, ключ обновления изменяется по мере изменения маршрута.
Вот демонстрация примера кода выше
FYI Max Larsson, из вашего кода,fadeIn
определяется как функция, которая не требует аргументов и возвращает объект, имеющий duration
свойство равное стоимости duration
переменная в этой области. то же самое сdelay
. Записьeasing
определяется как имя со значением sineOut
.
Это может быть вашей проблемой, если вы просто пытались поставить буквальный 0
где delay
был. Я вижу, ты пытался сделатьdelayZero
, но, вероятно, использовали его не так, как вы планировали. Вы, наверное, хотели написать это:
export const fadeOut = _ => ({
duration,
delay: 0,
easing: sineOut,
css: t => `opacity: ${t}`
});
Когда я попробовал это, у меня все заработало. Спасибо, что поделились своим примером.
Я предполагаю, что Svelte Kit изменился после ответа @GiorgosK, потому что я не могу заставить его работать с кодом в его ответе. Но, к счастью, его репозиторий на github был обновлен, спасибо! В
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 поделится своим мнением об этом изменении.