非SvelteKit环境下Svelte如何基于svelte-navigator创建动态路由
解决方案
核心问题是PostDetail组件没有读取动态路由的:id参数,组件初始化时post是空数组,执行fetch时post.id为undefined,自然无法拿到正确的详情数据。
第一步:在PostDetail中通过路由钩子获取参数
svelte-navigator提供useParams钩子读取路径匹配的动态参数,不要在组件内给post设空数组初始值后尝试读取它的id,直接用路由拿到的id发请求:
<!-- PostDetail.svelte --> <script> import { onMount } from 'svelte'; import { useParams } from 'svelte-navigator'; const params = useParams(); let post = null; let loading = true; let errMsg = ''; onMount(async () => { try { const res = await fetch(`http://localhost:8000/posts/${params.id}/`); if (!res.ok) throw new Error('帖子不存在或加载失败'); post = await res.json(); } catch (err) { errMsg = err.message; } finally { loading = false; } }); </script> {#if loading} <p class="text-center">加载中...</p> {:else if errMsg} <p class="text-danger text-center">{errMsg}</p> {:else} <article class="card"> <div class="card-body"> <h1 class="card-title h3">{post.name}</h1> <p class="card-text">{post.description}</p> <!-- 编辑、删除按钮放在这部分即可 --> </div> </article> {/if}
第二步:确认路由配置正确
你当前的嵌套路由写法逻辑没问题,只需要确保最外层包裹了<Router>组件即可:
<!-- routes/index.svelte --> <script> import { Router, Route } from 'svelte-navigator'; import Home from '../Home.svelte'; import PostDetail from '../PostDetail.svelte'; </script> <Router> <Route path="posts/*"> <Route path="/"> <Home /> </Route> <Route path=":id"> <PostDetail /> </Route> </Route> </Router>
你在Home.svelte里写的列表跳转逻辑<Link to={/posts/${post.id}}>是完全正确的,不需要修改。
后续编辑、删除功能实现参考
- 编辑功能:新增
/posts/:id/edit路由,挂载帖子编辑表单组件,在组件内同样通过useParams拿到帖子id,拉取原有内容填充表单,提交时发PUT请求到接口,成功后跳回详情页或列表页 - 删除功能:在详情页加删除按钮,绑定点击事件后发DELETE请求到
http://localhost:8000/posts/${params.id}/,请求成功后调用svelte-navigator的useNavigate钩子跳回帖子列表即可
内容的提问来源于stack exchange,提问作者user18752895
相关产品推荐
相关产品推荐

