Спасибо @three за ваш комментарий , который привел меня к ответу.
Если маршрут или _layout
компонент экспортирует preload()
, он всегда вызывается при навигации. В итоге я сделал это, сохранив извлеченные данные во втором параметре в preload()
, который обычно называется session
и, по-видимому, используется всеми компонентами. И я звонил this.fetch()
, только если данные еще не присутствовали.
<!-- blog/index.svelte -->
<script context="module">
export async function preload (page, session) {
let {posts} = session;
if (undefined === posts) {
const response = await this.fetch('blog/posts.json');
posts = await response.json();
session.posts = posts
}
return {posts}
}
</script>
<script>
export let posts;
</script>
{#each posts as post}
<!-- ... -->
{/each}
Затем в [slug].svelte
отметьте session.posts
для сообщения, которое вы ищете, и если его нет, загрузить его.
<!-- blog/[slug].svelte -->
<script context="module">
export async function preload (page, session) {
const {slug} = page.params
const {posts} = session
let post
if (undefined === posts) {
const response = await this.fetch(`blog/${slug}.json`)
post = await response.json()
} else {
post = posts.find(p => p.slug === slug)
}
if (undefined === post) {
this.error(404, "Sorry we couldn\'t find that post")
}
return {post}
}
</script>
<script>
export let post
</script>
<!-- ... render post -->
Теперь навигация происходит мгновенно. Для максимальной надежности вы можете добавить проверки для перезагрузки, если данные устарели (скажем, старше 5 минут, что угодно).
Редактировать
На самом деле вам не нужно использовать сеансы как таковые , Если вы просто хотите, чтобы параметр session
равнялся preload(page, session)
, а не был undefined
, вы можете использовать его в server.js
:
sapper.middleware({
// Define session parameter as an empty object
session: (req, res) => ({})
})