如何在SvelteKit中以编程方式进行路由?

52
我希望能够管理我SvelteKit应用程序的历史记录,同时确保整个SvelteKit路由系统不受任何影响。类似于:
function routeToPage(route: string) {
   router.push(`/${route}`) // equivalent of this function
}
4个回答

78

感谢来自 SvelteKit Discord 的 Theo,我自己回答了我的问题:

使用 $$app-navigation

import { goto } from '$app/navigation';

function routeToPage(route: string, replaceState: boolean) {
   goto(`/${route}`, { replaceState }) 
}

replaceState == true意味着替换路由而不是添加到浏览器历史记录。因此,当您单击后退按钮时,您将无法返回到您来自的那个路由。

要返回上一页,请使用History API

import { goto } from '$app/navigation';

function goBack(defaultRoute = '/home') {
  const ref = document.referrer;
  goto(ref.length > 0 ? ref : defaultRoute)
}

1
reflength 变量从哪里来? - laszlo
还有,你会在哪里/如何使用 goBack() - monsto
1
reflength is missing the dot operator: ref.length - edfonseca
这个不起作用,解释不够清楚。 - Bitfinicon
这在服务器上不起作用,我需要检查是否为服务器模式并忽略它。似乎在SSR上什么都不起作用。 - chovy
state 可以用于修改历史记录:goto(\/${route}`, {state: `/${route}`});`如果您想要覆盖当前的历史记录条目,请使用 replaceState:true - Malo Marrec

35
你可以使用 Svelte-Kit 的 goto 函数 以编程方式导航到路由。
最简单的实现方法可能是这样的:
<script> 
  import { goto } from '$app/navigation';
  goto("/route")
</script>

但是你也可以使用更高级的选项,将其作为第二个参数传递给目标路由。


8
服务器上无法调用goto(...)。 - Marche Remi
2
这个无法正常工作。在页面刷新时出现问题:无法在服务器上调用goto(...)。 - Bitfinicon
1
@Theoテオ,你是什么意思?能否分享一个例子? - seemcat
1
@seemcat 举例来说,一个评论框无法容纳这么多内容,但是这里有一个端点的文档 https://kit.svelte.dev/docs#routing-endpoints - Theo テオ
2
请发布示例。同时出现服务器错误。 - chovy
显示剩余4条评论

6
import { goto } from '$app/navigation';

function routeToPage(route: string) {
  goto(route);
}

3

这可能不完全是您正在寻找的内容,但我认为值得提及的是可以利用$app/navigation提供的beforeNavigate回调函数。

然后,您可以将导航历史记录保存在存储中,以便在整个应用程序中使用它来管理一些特殊情况。

/routes/__layout.svelte

<script>
$: console.log($previousPage, $nextPage);

import { beforeNavigate } from "$app/navigation";
    beforeNavigate(({ from, to }) => {
    $history = [to.pathname, ...$history];
});
</script>

{#if $history}
  <ul>
    {#each $history as url}
      <li>{url}</li>
    {/each}
  </ul>
{/if history}

附注: fromto 是来自 Web API 的 URL 对象: https://developer.mozilla.org/zh-CN/docs/Web/API/URL

/routes/stores.svelte

import { writable } from 'svelte/store';

export const history = writable(['/']);

这里是基于SvelteKit Demo应用的演示:

https://stackblitz.com/edit/sveltejs-kit-template-default-wivfds?file=src%2Froutes%2Fstores.js&terminal=dev


演示程序崩溃并显示错误:Error: Failed to load data at Renderer._load (https://sveltejskittemplatedefaultwivfds-gpaa--3000.local-corp.webcontainer.io/@fs/home/projects/sveltejs-kit-template-default-wivfds/.svelte-kit/runtime/client/start.js:1355:16) at async Renderer._get_navigation_result (https://sveltejskittemplatedefaultwivfds-gpaa--3000.local-corp.webcontainer.io/@fs/home/projects/sveltejs-kit-template-default-wivfds/.svelte-kit/runtime/client/start.js:1058:19) - Pick Avana
它还很粗糙,但出现了错误的页面是“todos”页,而不是崩溃。我已经删除了API部分,所以您可以再次测试它。 - Big_Boulard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接