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

如何在Sapper中处理可变深度嵌套路由,避免重复页面模板?

解决Sapper中多级动态分类路由的问题

嘿,我明白你的困扰——在Sapper里处理不固定层级的分类路由确实不像Nuxt那样直接能替换pages目录,但其实用它自带的catch-all动态路由就能完美解决,不用重复写模板。下面是具体的实现步骤:

1. 创建通用的Catch-All路由页面

在src/routes目录下新建一个[...slug].svelte文件,这个文件会匹配所有未被其他路由(比如首页、关于页)覆盖的路径,不管你的分类层级是1级还是4级。

2. 在页面中解析路由参数

Sapper会把动态路由的参数打包成数组传给params.slug,比如访问/tech/web/vue/guide.html,params.slug就是['tech', 'web', 'vue', 'guide.html']。我们需要在preload函数里拆分分类层级和页面slug:

<script context="module">
  export async function preload({ params }) {
    // 拆分分类数组和页面slug(移除.html后缀)
    const slugParts = [...params.slug];
    const pageSlug = slugParts.pop().replace(/\.html$/, '');
    const categories = slugParts;

    // 限制分类层级最多4级,超出返回404
    if (categories.length > 4) {
      this.error(404, '分类层级超出限制');
    }

    // 调用你的API获取对应页面数据,这里只是示例
    const pageData = await fetch(`/api/content/${categories.join('/')}/${pageSlug}`)
      .then(res => res.json());

    return { categories, pageSlug, pageData };
  }
</script>

<script>
  export let categories;
  export let pageSlug;
  export let pageData;
</script>

3. 渲染适配层级的UI

拿到分类层级后,你可以根据数组长度渲染对应的面包屑、导航或布局,比如:

<!-- 面包屑导航 -->
<nav class="breadcrumb">
  <a href="/">首页</a>
  {#each categories as cat, index}
    > 
    <a href="/{categories.slice(0, index + 1).join('/')}">{cat}</a>
  {/each}
  > {pageData.title}
</nav>

<!-- 页面内容区 -->
<article>
  <h1>{pageData.title}</h1>
  <div class="content">{@html pageData.content}</div>
</article>

4. 处理.html后缀的路由访问

Sapper默认的路由不带.html后缀,所以需要在server端加个重写规则,让用户访问带.html的路径能正确匹配到我们的catch-all路由。以默认的Polka服务器为例,修改src/server.js:

import polka from 'polka';
import * as sapper from '@sapper/server';

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';

polka()
  .use(
    // 重写.html路径,去掉后缀后交给Sapper处理
    (req, res, next) => {
      if (req.path.endsWith('.html')) {
        req.url = req.path.slice(0, -5);
      }
      next();
    },
    sapper.middleware()
  )
  .listen(PORT, err => {
    if (err) console.log('Error starting server:', err);
  });

5. 生成带.html的链接

如果你的页面导航需要生成带.html的链接(比如符合原有URL规范),直接在组件里拼接即可:

<a href="/{categories.join('/')}/{pageSlug}.html">{pageData.title}</a>

这样不管你的分类层级是1级还是4级,都只用这一个模板就能处理所有页面,完全不需要重复创建模板文件。

内容的提问来源于stack exchange,提问作者Elco Brouwer von Gonzenbach

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:01:40