【问题标题】:How to reuse fetch function in sveltekit如何在 sveltekit 中重用 fetch 函数
【发布时间】:2022-11-23 15:40:16
【问题描述】:

我有一个 sveltekit 页面正在运行,它让你指定一个兄弟页面 +page.ts,你可以在其中调用 load 方法来获取数据。但是,我想根据 +page.svelte 中的按钮或交叉点观察器进行分页。我是否必须重写要在 +page.svelte 中使用的函数?或者有没有一种方法可以在 page.ts 文件中使用它,然后使用来自 +page.svelte 的不同偏移量/等调用它?文档不显示此特定用例。

【问题讨论】:

    标签: svelte sveltekit


    【解决方案1】:

    随着“无限滚动”

    最初的答案是针对经典分页,见下文。

    如果您想将新数据附加到现有数据,进行某种“无限滚动”设置,首先要做的是创建一个可以从中获取数据的 api 端点。例如像这样:

    // file: /api/users/[[page]]/+server.js
    import { json } from '@sveltejs/kit';
    export async function GET({ params }) {
      // Get the requested page, or if not provided 0
      const page = params.page ?? 0;
      // For demo purposes
      const users = new Array(10).fill(0).map((_, index) => ({
        name: `User ${(page * 10) + index + 1}`
      }))
      // Return value
      return json(users)
    };
    

    现在您可以从客户端代码调用此 api 以获取更多代码,就像您使用任何其他 api 一样:

    <!-- file: +page.svelte -->
    <script lang="ts">
        export let data;
        let users = data.users;
        let page = data.page;
        function loadMore() {
          fetch(`/api/users/${++page}`)
            .then((res) => res.json())
            .then((res) => (users = [...users, ...res]));
        }
    </script>
    
    <ul>
        {#each users as user}
            <li>
                {user.name}
            </li>
        {/each}
    </ul>
    <button on:click={loadMore}>Load more</button>
    

    剩下的就是获取第一页,这可以通过从加载函数调用相同的 api 来简单地完成:

    // file: +page.js
    function load({ url }) {
      const users = await fetch(url.origin + '/api/users').then(res => res.json());
      return {
        // initial page 0
        page: 0,
        users
      }
    };
    

    使用“经典”分页

    这是对问题的误解的先前答案,但将其保留在这里以备不时之需。通过这种方法,您可以使用更“经典”的分页方式,您可以在许多地方看到类似 posts?index=0posts?index=1mysite/archives/page/1mysite/archives/page/2 的网址。

    这种方法的好处之一是用户可以轻松返回(“它在第 5 页的某处”)或链接到列表的特定部分。 (通过一些额外的工作,用链接替换按钮,它也可以工作没有客户端javascript)

    您可以将 searchparams 与加载函数一起使用,假设您有一个 url /mysite/posts?index=0,您可以配置加载函数以从索引 0 获取 10 个帖子

    export async function load({ url }) {
      const index = url.searchParams.get('index') ?? 0; // defaults to 0
      // other code goes here
      return {
        posts,
        index
      }
    }
    

    如果你有,第二部分就变得微不足道了,只需“导航”到具有下一个索引的页面:`

    goto(`/posts?index=${data.index + 1}`)
    

    SvelteKit 将看到它是同一个页面,执行匹配的load 并用新帖子填充data(这就是为什么我也返回索引,这样更容易)。虽然 url 发生了变化(使共享更容易),但没有真正的导航.您甚至可以使用实际链接更改 goto 以使整个解决方案无需 javascript 即可工作:

    <a href="/posts?index={data.index - 1}">Previous</a>
    <a href="/posts?index={data.index + 1}">Next</a>
    

    【讨论】:

    • 这是 svelte 的推荐使用模式吗?只是看起来很“hacky”——尽管根据定义,很多 svelte 都是 hacky。
    • 对不起,哪一部分是hacky?答案的第一部分允许您直接转到分页中的特定页面(便于共享链接)第二部分使用简单导航到该页面即可工作的事实还有其他方法(在其他框架中使用)比那更骇人听闻
    • 导航到页面本身特别取决于选择不重新呈现的苗条。根据定义,导航以加载更多数据是 hacky。你不同意吗?
    • 等等,你加载的是“更多”数据还是“不同”数据,比如无限滚动与第 1 页、第 2 页、第 3 页?
    • 加载更多数据。我从来没有遇到过一种设计模式,您可以从页面“离开”导航回到自身以获取更多数据。特别是因为我想连接列表,这将涉及页面知道存在哪些数据它被称为。我知道 Svelte 会“破解”某些 JS 字符和标记,因此将其作为最佳实践并不少见。乍一看,我想避免这种模式。
    猜你喜欢
    • 2020-02-23
    • 2019-12-23
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2020-04-19
    • 2019-02-05
    相关资源
    最近更新 更多