如何在 Sveltekit 中的页面之间保持 _layout 状态

How to persist _layout state between pages in Sveltekit

我的 __layout.svelte 中有一个变量 checked,我希望该值在页面导航之间保持不变。相反,当我导航到新页面时,checked 会重置为默认值 false。有没有一种方法可以简单地在页面加载之间保持布局或应用程序状态?

问题的上下文是我需要在应用程序的页面导航中维护 checked 的值,这是一个手动暗模式开关。

<!-- __layout.svelte -->
<script>

  let checked = false

  $: checked, console.log('checked is', checked)

</script>

<a href="/">Home</a>
<a href="/about">About</a>
<a href="/contact">Contact</a>

<div style="margin-top:2em">
  <label>
    <input type="checkbox" bind:checked/>
    a checkbox...
  </label>
</div>

<slot></slot>

这是 Svelte Store 的一个很好的例子。 (Docs)

最佳做法是创建一个包含存储变量的文件。在这种情况下,我在 lib 文件夹中调用了文件 store.js

store.js:

import { writable } from "svelte/store";

export const checked = writable(false); // set the default value to false

您现在可以在项目的任何地方使用 <script/> 标签中的以下行导入此商店:

import {checked} from '$lib/store.js';

您也可以像这样将此商店绑定到复选框:

<input type="checkbox" bind:checked={$checked}/>

这可能是您的 index.svelte 文件,它将自动更新 <h1/> 标签:

<script>
  import {checked} from '$lib/store.js';
</script>

<h1>{$checked}</h1>

Svelte Store 提供更多功能(订阅、派生或可读商店,...)。因此,我链接了上面的 (Docs)。


编辑:通过使用浏览器扩展这个概念 localStorage 允许我们跨浏览器会话保存数据 (Source)。

下面的例子:

  1. 订阅 Svelte 可写
  2. 检查 if (browser) - 由于 SSR,服务器会抛出错误,因为它没有 localStorage
  3. 使用JSON解析器,因为localStorage只保存Strings而不保存Booleans

已更新 store.js 文件:

import { writable } from "svelte/store";
import { browser } from "$app/env";

export const checked = writable();

if (browser){
    checked.set(JSON.parse(localStorage.getItem("checked")) || false);
    checked.subscribe(value => {
        localStorage.setItem("checked", JSON.stringify(value));
    });
}