通过槽将变量从页面向上传递到svelte布局

vin*_*lti 12 svelte svelte-3 sveltekit

所以我无法找到一种方法来在我的__layout<slot>.

\n

我尝试了一些方法,使用bind:let:在插槽上,但它不起作用。我得到\'myvar\' is not a valid binding<slot> cannot have directives
\n我也尝试导出或不导出布局上的变量,但我真的无法使其工作......

\n

这是我所拥有的:

\n
 <!-- __layout.svelte -->\n<script>\nexport let myvar = undefined;\n</script>\n\n<main>\n  <slot myvar={myvar}></slot>\n  <p>Layout myvar: {myvar}</p>  <!-- << This will stay undefined -->\n</main>\n
Run Code Online (Sandbox Code Playgroud)\n
 <!-- mypage.svelte -->\n<script>\nimport MyComponent from "$lib/my_component.svelte";\nexport let myvar;\nlet a_list_of_things = [1,2,3,4]\n</script>\n\n<main>\n  {#each a_list_of_things as thing}\n    <MyComponent bind:myvar={myvar} thing={thing}/>  <!-- The variable is binded here -->\n  {/each}\n  <p>mypage myvar: {myvar}</p>   <!-- << This will get the good value -->\n</main>\n
Run Code Online (Sandbox Code Playgroud)\n
 <!-- my_component.svelte -->\n<script>\nimport IconButton from \'@smui/icon-button\'\n\nexport let myvar;\nexport let thing;\n</script>\n\n<div>\n  <IconButton class="material-icons" on:click={() => myvar=\'something\'} >\n    autorenew\n  </IconButton>  <!-- << We change the value on:click here -->\n\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n

所以主要目标是在布局级别上有一个等价的bind:myvar=myvar(对于<slot></slot>.

\n

我尝试理解文档,但没有取得多大成功,它似乎更多地是关于组件插槽而不是布局。

\n
\n

我发现另一个问题建议使用 sapper 中的商店(sveltekit 的旧名称),不确定它是否与 sveltekit 的最新版本保持同步,这是要走的路吗?或者还有其他方法吗?

\n

其他人建议使用上下文。你怎么认为 ?

\n
\n

为什么我需要这个?

\n

所以我的应用程序的结构如下:

\n
__layout\n \xe2\x94\x9c\xe2\x94\x80 header (menu)\n \xe2\x94\x9c\xe2\x94\x80 my_page (<slot>)\n \xe2\x94\x82   \xe2\x94\x94 my_component (many)\n \xe2\x94\x94 interactive banner\n
Run Code Online (Sandbox Code Playgroud)\n

像这样显示它:

\n
[ Header Menu ]\n\nContent of the page\n - component 1\n - component 2\n - component n\n\n[ Current component: 2 ] << Updated when click on an elem in the component\n
Run Code Online (Sandbox Code Playgroud)\n

定义component交互式横幅应显示的内容。还可以单击interactive banner可以更改显示在中的状态components

\n

Geo*_*ich 5

由于此横幅消息似乎是全局状态的一部分,因此商店将是一个很好的解决方案。仅当您需要为页面上的不同组件树使用不同的横幅时,才需要上下文。

像这样的事情会起作用:

// src/lib/message.js
import { writable } from 'svelte/store';

export default writable('Default message');
Run Code Online (Sandbox Code Playgroud)
<!-- src/routes/__layout.svelte -->
<script>
    import message from '$lib/message';
</script>

<slot />
<p>{$message}</p>
Run Code Online (Sandbox Code Playgroud)
<!-- src/routes/index.svelte -->
<script>
    import message from '$lib/message';

    function update() {
        $message = 'New message';
    }
</script>

<h1>Hello World</h1>

<button on:click={update}>Update message</button>
Run Code Online (Sandbox Code Playgroud)

  • 在“message.js”中,我们创建并导出 Svelte 商店。任何组件都可以使用“$store”语法导入和订阅商店。当商店更新时,任何订阅该商店的人都会收到通知。这允许我们更新“index.svelte”中的存储并自动接收“__layout.svelte”中的新值。如果您还没有阅读过[关于商店的 Svelte 教程](https://svelte.dev/tutorial/writable-stores),我强烈建议您阅读一下,因为它们是一个重要的 Svelte 概念。 (2认同)
  • 这个答案显然给出了解决方案,但这是唯一的解决方案吗?有没有办法绑定到 &lt;slot&gt; 或者根本不起作用? (2认同)