【问题标题】:Send data from one page to another instead of preloading?将数据从一页发送到另一页而不是预加载?
【发布时间】:2020-05-28 18:39:20
【问题描述】:

假设我有一个 blog 路由,可以加载所有博客文章的完整数组。个人博客帖子位于blog/[postId]。是否有一种 Sapper 惯用的方式将单个帖子的数据从 blog 传递到 blog/[postId]

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

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

【问题讨论】:

  • 你可以在你的布局路线中做到这一点。如果它位于您的博客目录中,您可以在其中预加载所有帖子,然后根据每个 ID 显示该数据。但我可能只预加载一个博客 ID,然后在加载后获取所有其他帖子并将它们存储在商店中。
  • 感谢您的建议。它让我走上了解决问题的道路。结果发现preload() 总是在导航时被调用,不管它是在_layout.svelte 中,还是在常规页面组件中,或者两者兼而有之。我最终将第二个参数中的数据存储到preload()session,并且只有在它为空或陈旧时才调用this.fetch()

标签: svelte sapper svelte-3


【解决方案1】:

感谢@three 为your comment 提供了答案。

如果路由或_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) => ({})
})

【讨论】:

  • 很高兴它有帮助!
猜你喜欢
  • 2012-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-30
  • 2020-08-16
  • 1970-01-01
  • 2013-01-24
  • 1970-01-01
相关资源
最近更新 更多