当前位置: 首页 > news >正文

【Svelte】加载数据实现响应式的正确方式

+page.ts 中使用load加载数据时,必须等待load处理完毕,页面才能获取数据并显示。

下面是一个关于 SvelteKit 中 +page.ts (或 +layout.ts) 的 load 函数工作方式的常见误解。

为什么在 +page.ts 中更新页面内容不起作用:

  1. load 函数优先于组件渲染: load 函数在 +page.svelte 组件(或任何会显示你的加载指示器的 UI 部分)被挂载或开始根据 load 返回的数据渲染其初始状态之前执行。
  2. (针对 UI 的)同步执行上下文: 即使 is_loading.value = true 理论上可以更新一个 store,UI 也不会对它做出反应,直到 load 函数完成其整个执行并返回数据。SvelteKit 需要这些数据来准备组件的 props。
  3. 没有即时 UI 重新渲染机制:load 函数内部没有一种机制可以“暂停”其执行,触发 UI 更新以显示加载指示器,然后再恢复。load 函数必须完成它的工作(包括 await fetch),然后组件才能开始考虑渲染。

SvelteKit 的正确方式:在 +page.svelte 组件中使用 {#await}

SvelteKit 旨在优雅地处理这种精确的场景。与其尝试在 load 函数内部管理 loading 状态,不如从 load 函数返回一个 Promise,然后在你的 +page.svelte 组件中使用 Svelte 内置的 {#await} 块。

以下是实现方法:

1. 修改 +page.ts 以返回一个 Promise:

你直接返回 Promise 本身,而不是 await fetch 调用并返回数据。

// src/routes/your-page/+page.ts
import type { PageLoad } from './$types';
import { API } from '$lib/api'; // 假设你有一个 API 配置export const load: PageLoad = async ({ fetch }) => {// 我们创建一个函数,它返回 fetch 的 Promiseconst fetchRoomData = async () => {const response = await fetch(API.room); // 你的实际 fetch 调用if (!response.ok) {throw new Error('Failed to load room data');}return await response.json();};// 关键改变:直接返回 Promise,不要在这里 await 它!return {roomData: fetchRoomData()};
};

2. 修改 +page.svelte 以使用 {#await}

现在,在你的组件中,你将收到 data.roomData 作为一个 Promise。然后,你可以使用 {#await} 根据 Promise 的状态显示不同的内容。

<!-- src/routes/your-page/+page.svelte -->
<script lang="ts">import type { PageData } from './$types';// 这个 'data' prop 将包含来自 +page.ts 的 'roomData' Promiseexport let data: PageData;
</script><h1>房间详情</h1>{#await data.roomData}<!-- 在 Promise 待处理时显示的内容(这里放加载指示器!) --><div class="spinner-container"><div class="spinner"></div><p>正在加载房间数据...</p></div>
{:then room}<!-- 在 Promise 成功解决时显示的内容 --><p>房间名称: {room.name}</p><p>容量: {room.capacity}</p><p>状态: {room.status}</p><!-- 渲染其他房间属性 -->
{:catch error}<!-- 如果 Promise 拒绝(fetch 失败)时显示的内容 --><p style="color: red;">错误: {error.message}</p><p>请稍后再试。</p>
{/await}<style>.spinner-container {display: flex;flex-direction: column;align-items: center;gap: 10px;padding: 20px;border: 1px solid #eee;border-radius: 8px;background-color: #f9f9f9;}.spinner {border: 4px solid rgba(0, 0, 0, 0.1);width: 36px;height: 36px;border-radius: 50%;border-left-color: #007bff; /* SvelteKit 蓝色或你的品牌色 */animation: spin 1s ease infinite;}@keyframes spin {0% { transform: rotate(0deg); }100% { transform: rotate(360deg); }}
</style>

解释:

  1. 当用户导航到 /your-page 时,SvelteKit 会运行 +page.ts
  2. +page.ts 立即返回一个包含 roomData 的对象,roomData 是一个最终会以房间数据解决的 Promise
  3. SvelteKit 将此对象传递给 +page.svelte
  4. +page.svelte 开始渲染。{#await data.roomData} 块会立即进入其 {:pending} 状态,因为 data.roomData 仍然是一个待处理的 Promise。你的加载指示器和“正在加载…”消息会显示出来。
  5. 在组件渲染并显示加载指示器时,fetchRoomData() 的 Promise 会在后台继续解决。
  6. 一旦 fetchRoomData() 解决(或拒绝),{#await} 块会自动更新,显示 {:then room} 内容或 {:catch error} 内容。

这种方法确保加载指示器在组件渲染后立即可见,数据到达之前,从而提供了更好的用户体验。

考虑使用 +page.server.ts 进行数据获取:

对于大多数不依赖客户端浏览器 API(如 localStorage)的数据获取场景,通常建议使用 +page.server.ts 来编写你的 load 函数。这提供了:

  • 服务器端渲染 (SSR): 数据在服务器上获取,并直接包含在初始 HTML 中,使得页面在首次加载时完全渲染。
  • 安全性: API 密钥和敏感逻辑可以保留在服务器上。
  • 性能: 更快的初始加载,因为浏览器不必等待 JavaScript 执行然后再获取数据。

如果你将 fetch 移动到 +page.server.ts,那里的 load 函数会 await fetch,组件将直接接收已解决的数据。对于后续的客户端导航,SvelteKit 会在后台执行 fetch,如果数据没有立即可用,会隐式使用 {#await}

然而,当你想在客户端导航期间显示加载指示器,或从 load 函数返回 Promise 时,上述的 {#await} 模式仍然是处理待处理数据的正确方式。

http://www.dtcms.com/a/439251.html

相关文章:

  • 出售自己的网站Add-ons wordpress
  • 网络安全相关的专业术语
  • 帝国cms影视网站模板宁波网站制作哪家强
  • (一)算法
  • 23ICPC济南站补题
  • 商务网站建设ppt模板培训网站排名
  • 南阳市宛城区建设局网站设计本质
  • nacos使用指南
  • 中山AI搜索哪家好?GEO优化与传统SEO深度解析
  • MySQL优化----非查询SQL优化
  • 影视网站代理徐州市经济技术开发区建设局网站
  • 基于单片机的三相逆变电源设计
  • Python基础入门例程92-NP92 公式计算器
  • MyCat实现分库分表
  • 宿迁网站建设公司宣传海报制作
  • 中铁中基建设集团网站品牌形象网站源码
  • 中医院网站源码传智黑马培训机构
  • python全栈(基础篇)——day01:环境准备(python解释器安装+pycharm专业版的下载+vscode编辑器+汉化设置)
  • CodeForces Round 1054(div.3)C题
  • 南宁网站建设制作定制seo搜索引擎优化招聘
  • 3.java常用类知识点
  • 费马小定理证明
  • 建设中网站源码微信小程序怎么注册申请
  • iis7.5 没有默认网站彩票网站代理
  • 汇编语言Debug工具与常用指令完全指南
  • wordpress 托管建站有了公网ip如何做网站
  • 网站的费用多少合肥网站开发建设
  • 零基础学习做网站蚌埠做网站建设费用
  • 麒麟系统安装后添加自启动
  • 网站底部备案号悬挂佛山木工机械厂骏域网站建设专家