SvelteKit中重置布局的路由无法加载父路由数据问题
SvelteKit布局重置后父路由load数据无法传递,子路由load函数不执行
我在SvelteKit项目开发中,需要将films/[slug]/+layout.server.ts加载的数据传递到子路由films/[slug]/player/+page.server.ts的load函数中,供页面组件使用。同时该子路由需要重置为根布局(隐藏页脚、导航栏等元素),按照官方文档的@语法实现布局重置后,出现以下问题:
- 父路由的load数据无法传递到子路由
- 子路由的
+page.server.ts的load函数未正常执行,页面组件的data属性为undefined
项目目录结构
📦routes ┣ 📂(app) ┃ ┣ 📂films ┃ ┃ ┣ 📂[slug] ┃ ┃ ┃ ┣ 📂player ┃ ┃ ┃ ┃ ┣ 📜+page.server.ts (尝试从父路由加载数据) ┃ ┃ ┃ ┃ ┗ 📜+page.svelte (渲染load函数返回的数据) ┃ ┃ ┃ ┣ 📜+layout.server.ts (从API加载影片数据) ┃ ┃ ┃ ┗ 📜+page.svelte ┃ ┃ ┣ 📜+page.server.ts ┃ ┃ ┗ 📜+page.svelte ┃ ┣ 📜+layout.svelte ┃ ┗ 📜+page.ts ┗ 📜+layout.svelte (播放器路由需要应用此根布局)
相关代码片段
父路由 films/[slug]/+layout.server.ts
// films/[slug]/+layout.server.ts import { error } from '@sveltejs/kit'; import type { LayoutServerLoad } from './$types'; export const load = (async ({ fetch, params }) => { const filmId = params.slug; const res = await fetch(`/api/films/${filmId}`); if (!res) throw error(404, 'Film not found'); const filmData = await res.json(); if (!filmData) throw error(404, 'Film not found in database'); return { filmId, filmData }; }) satisfies LayoutServerLoad;
子路由 films/[slug]/player/+page.server.ts
// films/[slug]/player/+page.server.ts import type { PageServerLoad } from './$types'; export const load = (async ({ parent }) => { const { filmId, filmData } = await parent(); console.log('playerlayout', { filmId, filmData }); return { filmId, filmData }; }) satisfies PageServerLoad;
子路由页面 films/[slug]/player/+page.svelte
<!-- films/[slug]/player/+page.svelte --> <script lang="ts"> import { onMount } from 'svelte'; import { currentFilm } from '$lib/stores/films'; import FilmPlayer from '$lib/components/Player/VimeoPlayer.svelte'; import type { PageData } from './$types'; export let data: PageData; console.log('player', data); if (!$currentFilm) { currentFilm.set(data); } const fd = data.filmData; if (!fd.vimeoId) throw new Error('No video found for film'); const vimeoId = fd.vimeoId; let urls: {hls:string; lq:string;}; async function videoUrls() { const response = await fetch('/api/films/videourls', { method: 'POST', body: JSON.stringify({ vimeoId }), headers: { 'content-type': 'application/json' } }); urls = await response.json(); } onMount(() => { videoUrls(); }); </script> <main> <div class="max-h-screen h-full player"> {#if urls} <FilmPlayer {vimeoId} filmTitle={`${fd.title} (${fd.courseYear-1} - ${fd.courseYear})`} {urls} fullscreen={true}/> {/if} </div> </main>
项目依赖版本
@sveltejs/kit@1.11.0 @sveltejs/vite-plugin-svelte@2.0.3 @sveltejs/adapter-auto@2.0.0 svelte@3.57.0 vite@4.1.4
当前问题表现
- 不使用
@布局重置时,数据加载正常,但子路由会继承父路由的布局(显示不需要的页脚、导航栏) - 使用
+layout@.svelte重置布局后:- 首次导航到播放器路由显示空白页,控制台输出
playerlayout { filmId: undefined, filmData: undefined } - 刷新页面会抛出
TypeError: Cannot read properties of undefined (reading 'vimeoId')错误
- 首次导航到播放器路由显示空白页,控制台输出
- 尝试多种文件组合仍无法解决,目前有临时解决方案,但希望找到根本解决办法
内容的提问来源于stack exchange,提问作者Johannes Knudsen
相关产品推荐
相关产品推荐

