You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 11:25:03