SvelteKit中如何为多路由动态生成加载函数以避免代码重复?
SvelteKit中如何为多路由动态生成加载函数以避免代码重复?
我太懂这种被重复代码缠上的感觉了——每个+page.ts里都写着几乎一模一样的load逻辑,哪怕抽了helper函数,还是要在每个文件里写调用、返回结构,Boilerplate拉满,完全没必要。下面给你几个实用的方案,彻底把重复代码干掉:
方案1:用高阶工厂函数生成Load函数(最推荐)
核心思路是写一个能生成符合SvelteKit规范的load函数的工厂函数,把所有重复的逻辑(比如fetch、错误处理、基础数据解析)都封装在工厂里,每个路由只需要传入个性化的配置(比如API地址、数据转换逻辑)就行。
首先在你的工具目录里创建工厂函数,比如 src/lib/utils/load-factories.ts:
import type { PageLoad } from './$types'; // 定义配置项的类型,确保类型安全 type PageLoadConfig<T> = { // API接口地址 endpoint: string; // 可选:对返回数据做个性化转换的函数 transformData?: (rawData: unknown) => T; }; // 工厂函数:接收配置,返回SvelteKit要求的load函数 export function createPageLoad<T>(config: PageLoadConfig<T>): PageLoad { return async ({ fetch }) => { try { // 重复的fetch逻辑统一在这里处理 const response = await fetch(config.endpoint); if (!response.ok) throw new Error(`请求失败:${response.status} ${response.statusText}`); let data = await response.json(); // 如果有自定义转换逻辑,就处理数据 if (config.transformData) { data = config.transformData(data); } return { data }; } catch (error) { // 统一的错误处理,不用每个页面都写 console.error('加载数据出错:', error); return { error: error as Error }; } }; }
然后在你的每个+page.ts里,只需要一行代码导出load:
import { createPageLoad } from '$lib/utils/load-factories'; // 只需要传入当前路由的专属配置 export const load = createPageLoad({ endpoint: '/api/posts', // 可选:比如把后端返回的时间字符串转成Date对象 transformData: (raw) => raw.posts.map(post => ({ ...post, publishDate: new Date(post.publishDate) })) });
这样一来,每个路由的+page.ts里就只剩配置代码,完全没有重复的加载逻辑了!
方案2:结合路由路径自动映射API端点(适合路径对齐的场景)
如果你的路由路径和API接口路径是一一对应的(比如路由/posts对应/api/posts,路由/users/[id]对应/api/users/[id]),还能进一步简化,让工厂函数自动根据当前路由的URL生成API地址:
修改工厂函数,支持通过当前页面URL动态生成endpoint:
export function createPageLoad<T>(config: { getEndpoint: (pageUrl: URL) => string; transformData?: (rawData: unknown) => T; }): PageLoad { return async ({ fetch, url }) => { // 自动根据当前页面URL生成API地址 const endpoint = config.getEndpoint(url); // 后面的fetch、错误处理逻辑和方案1一致 try { const response = await fetch(endpoint); if (!response.ok) throw new Error(`请求失败:${response.status}`); let data = await response.json(); if (config.transformData) data = config.transformData(data); return { data }; } catch (error) { console.error('加载错误:', error); return { error: error as Error }; } }; }
然后在+page.ts里:
import { createPageLoad } from '$lib/utils/load-factories'; // 自动把路由路径转成API路径,比如/posts → /api/posts export const load = createPageLoad({ getEndpoint: (url) => `/api${url.pathname}`, // 可选的转换逻辑 });
这种方式连endpoint都不用手动写了,完全自动化!
额外优化:统一错误处理与类型安全
- 类型安全:工厂函数里用了泛型
<T>,你可以在调用时指定数据类型,比如createPageLoad<Post[]>(...),这样返回的data会自动带上类型提示,完美适配SvelteKit的类型系统。 - 自定义错误行为:如果不同路由需要不同的错误处理(比如有的路由要跳转到404,有的要显示错误提示),可以把错误处理函数也做成配置项传入工厂函数,进一步灵活定制。
内容来源于stack exchange
相关产品推荐
相关产品推荐

