动态路线在它们之间导航时不会刷新

Kev*_*ers 2 sveltekit

示例项目: https: //github.com/kevinrenskers/slug

基本上我有一条路线/[slug],代码如下:

// +page.svelte
<script lang="ts">
  import type { PageData } from "./$types";
  export let data: PageData;
  const { slug } = data;
</script>

{slug}
Run Code Online (Sandbox Code Playgroud)
// +page.ts
import type { PageLoad } from "./$types";

export const load: PageLoad = async ({ params }) => {
  const slug = params.slug;

  return {
    slug,
  };
};
Run Code Online (Sandbox Code Playgroud)

在我的+layout.svelte文件中,我有一个非常简单的导航:

// +layout.svelte
<a href="/a">A</a> <a href="/b">B</a> <a href="/c">C</a>

<div>
  <slot />
</div>
Run Code Online (Sandbox Code Playgroud)

问题是,当您在三个页面之间单击时,页面的内容不会改变。因此,如果您从主页转到 A,它会显示 A,但如果您随后单击 B 或 C,它仍然会显示 A。直到您刷新页面。

编辑:
我认为替换const { slug } = data可以$: slug = data.slug解决问题。所以我猜当您在相同的路线之间导航时,该页面不会重新创建?有点令人困惑,非常欢迎一个好的解释。

Ste*_*aes 5

正如您已经发现的那样,这确实是由于反应性造成的。要了解发生的情况,您必须了解 Svelte 如何与普通组件一起工作(您会看到相同的问题)

让我们假设这个完全无用的组件:

<script>
  export let name;
  console.log(name);
</script>
Run Code Online (Sandbox Code Playgroud)

当安装此组件时,它将正确记录传递的名称,但是当更改传递给组件的名称时,其中的代码script不会再次执行(这与 React 等框架相反),并且浏览器永远不会将任何内容记录到控制台再次。

这就是 Svelte 反应性的用武之地。在 Svelte 中,您明确告诉编译器:“如果 x 发生变化,则 y 发生变化”。所以要再次运行日志你会这样做

$: console.log(name);
Run Code Online (Sandbox Code Playgroud)

考虑到如果我会这样做

export let name
const NAME = name.toUpperCase();
Run Code Online (Sandbox Code Playgroud)

那么第二行只会在初始运行时执行一次,并且始终是大写的第一个名称。

现在也很容易理解 SvelteKit 中发生的事情了。在 SvelteKit 中,页面只不过是(更高级的)组件。因此,如果您在同一个 slug 下从一个页面转到另一页面,它将保留当前组件并更新属性data

这导致以下结果:

// New data is provided when navigating
export let data
// This line never executes again just like in a regular component
const { slug } = data;
Run Code Online (Sandbox Code Playgroud)

这就是全部内容。