我尝试在 Svelte 5 应用程序中使用 page.js 进行客户端路由,但遇到了一个奇怪的现象:当我将路由逻辑放在
App.svelte
组件中时,一切正常:
<!-- App.svelte -->
<script lang="ts">
import router from "page"
import Index from "./pages/index.svelte"
import About from "./pages/about.svelte"
import NotFound from "./pages/404.svelte"
let Page = $state(Index)
router("/", () => Page = Index)
router("/about", () => Page = About)
router("*", () => Page = NotFound)
router.start()
</script>
<Page/>
但是,一旦我尝试将此逻辑提取到外部模块中,路由就会失败,并且到其他页面的链接不会执行任何操作:
// router.svelte.ts
import router from "page"
import Index from "../pages/index.svelte"
import About from "../pages/about.svelte"
import NotFound from "../pages/404.svelte"
let page = $state(Index);
export const createRouter = () => {
const registerRoutes = () => {
router("/", () => page = Index)
router("/about", () => page = About)
router("*", () => page = NotFound)
router.start()
}
return {
get page() {
return page
},
registerRoutes,
}
}
现在,当我从 App.svelte 文件调用此路由器时,页面最初加载正确,但页面之间的链接不再起作用:
<!-- App.svelte -->
<script lang="ts">
import {createRouter} from "./router.svelte";
const router = createRouter()
router.registerRoutes()
let Page = router.page
</script>
<Page/>
我认为我对所涉及的反应性存在误解,但也许有人可以指出我正确的方向。
问题是:
let Page = router.page
这是一次性赋值,因此页面的后续更改不会更新该变量。您在这里需要一个
$derived
:
let Page = $derived(router.page);