将数据从一个页面发送到另一个页面而不是预加载?



假设我有一个blog路由,可以加载所有博客文章的完整数组。个别博客文章直播在blog/[postId].有没有一种工兵惯用法将单个帖子的数据从blog传递到blog/[postId]

从本质上讲,如果您在blog我想预加载用于显示blog/[postId]的代码。然后,当您单击指向blog/[postId]的链接时,立即导航到该链接并显示来自blog的数据。但是,当然,如果您直接导航到blog/[postId]那么仍然应该调用preload()

prefetch并没有完全做到这一点,因为这仍然需要网络请求。我还尝试了检查商店的预加载,除非网络请求为空,否则不会发出网络请求,但你不能在<script context="module">中使用商店。

感谢您的评论@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) => ({})
})

相关内容

  • 没有找到相关文章

最新更新