如何在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
相关产品推荐
相关产品推荐

