2

我知道 sapper 中的 session 是一个可写的存储。我可以这样写:

<script>
    import { stores } from "@sapper/app"
    const { session } = stores()
    session.set("new value")
</script>

但是,我很难在预加载函数中写入:

<script context="module">
    export async function preload(page, session) {
        session = "new value" // not working, this is just a value, not a store
    }
</script>

我需要在_layout.svelte预加载期间在那里设置一些数据。有什么支持的方法吗?

编辑 我最终没有使用会话,只是一个简单的可写存储。它不是那么干净,但它可以达到目的。如果有人找到方法或将来支持它,请保持打开状态。

4

2 回答 2

3

这里的session参数不是会话存储,它是别的东西。它在文档中被提及:

session 是通过传递给 sapper.middleware 的 session 选项在服务器上生成的(TODO 这需要进一步的文档。也许是服务器 API 部分?)

编辑:

[以前的建议删除,因为不正确]

为了完整性:显然sessionsession商店有关,参数是商店的价值。但是,您仍然无法以有意义的方式对其进行写入。

就像我在评论中说的那样,我认为您想做的事情在preload. 也许我错了,别人可能会告诉你。

同时,我建议以下解决方法:在 _layout 组件实例中执行所有这些操作。在那里,您可以完全访问商店。像这样的东西,例如:

<script>
  import { stores } from '@sapper/app'

  import { resolveAuth } from './your/utils'

  const { session } = stores()

  resolveAuth()
    .then(auth => { $session = auth })
    .catch(err => { ... })
</script>

{#if $session}
  <slot />
{:else}
  <!-- loading indicator... or not -->
{/if}

于 2019-12-02T19:41:52.887 回答
2

如前所述,预加载中的会话变量与您的会话存储不同......它们只是碰巧共享相同的名称,并且它之所以有效,是因为它们在范围内彼此隔离。

preload 功能——由 sapper 提供——在客户端和服务器上运行,而 store——因为它们是 svelte 的一部分——只存在于客户端上,所以就我而言,将 store 导入 preload 是不可能的知道的。

就我而言,在第一次访问我的应用程序时,如果客户端已经存在会话,我想使用 HttpOnly cookie 更新会话。对我来说,这段代码最明显的地方是 _layout.svelte 文件。

我的解决方法最终是创建一个currentSession变量并将会话数据分配给它,如下所示:

<script context="module">
    export async function preload(page, session) {
        let currentSession = session;
        return { currentSession };
    }
</script>

然后,在我的主脚本标签中

<script>
export let currentSession; // <-- Needs export because it's a prop.
import { session } from '../stores.js';
session.set(currentSession);

// ...Do more stuff...
</script>

这并没有做理想的事情——我们都想要——会话变量在导入时已经作为带有会话数据的存储存在,但我猜这是下一个最好的事情。主要的好处是,如果你用类似的东西初始化你的商店,let session = writeable(null);那么在你的组件加载时$session将不再是这样。null

如果你想出了更好的方法,请告诉我。谢谢。

于 2020-12-15T13:52:06.243 回答