通过插槽将变量从页面向上传递到 svelte 布局
Pass variable up from page to svelte layout via slot
所以我想不出一种方法来从 <slot>
.
中显示的组件向我的 __layout
变量传递一个变量
我尝试了一些方法,在插槽上使用 bind:
或 let:
,但它不起作用。我得到 'myvar' is not a valid binding
或 <slot> cannot have directives
.
我也尝试导出或不导出布局上的变量,但我真的无法让它工作...
这是我的:
<!-- __layout.svelte -->
<script>
export let myvar = undefined;
</script>
<main>
<slot myvar={myvar}></slot>
<p>Layout myvar: {myvar}</p> <!-- << This will stay undefined -->
</main>
<!-- mypage.svelte -->
<script>
import MyComponent from "$lib/my_component.svelte";
export let myvar;
let a_list_of_things = [1,2,3,4]
</script>
<main>
{#each a_list_of_things as thing}
<MyComponent bind:myvar={myvar} thing={thing}/> <!-- The variable is binded here -->
{/each}
<p>mypage myvar: {myvar}</p> <!-- << This will get the good value -->
</main>
<!-- my_component.svelte -->
<script>
import IconButton from '@smui/icon-button'
export let myvar;
export let thing;
</script>
<div>
<IconButton class="material-icons" on:click={() => myvar='something'} >
autorenew
</IconButton> <!-- << We change the value on:click here -->
</div>
所以主要目标是在布局级别上有一个等同于 bind:myvar=myvar
的对象(对于 <slot></slot>
.
我尝试理解 documentation 关于它的内容,但没有成功,它似乎更多地是关于组件槽而不是布局槽。
我发现 建议在 sapper(sveltekit 的旧名称)中使用商店,不确定它是否与最新版本的 sveltekit 保持同步,这是可行的方法吗?或者还有其他方法吗?
建议使用上下文。你怎么看?
为什么我需要这个?
所以我的应用程序结构如下:
__layout
├─ header (menu)
├─ my_page (<slot>)
│ └ my_component (many)
└ interactive banner
这样显示:
[ Header Menu ]
Content of the page
- component 1
- component 2
- component n
[ Current component: 2 ] << Updated when click on an elem in the component
component
定义交互式横幅应显示的内容。同样点击interactive banner
可以改变components
中显示的状态
我在下面给出了一个带有命名插槽的示例,也未命名 ->
在Slot.svelte
<script>
let content ='lorem'
</script>
<slot name='named-slot' >
{content}
</slot>
在父组件中
<script>
import Data from './Slot.svelte'
let newData=' new content'
</script>
<Data>
<svelte:fragment slot='named-slot' let:newData={content}>
{newData}
</svelte:fragment>
</Data>
以及未命名插槽的示例 ->
在Slot.svelte
<script>
let content ='lorem'
</script>
<slot >
{content}
</slot>
在父组件中
<script>
import Data from './Slot.svelte'
let newData=' new content'
</script>
<Data let:newData={content}>
{newData}
</Data>
由于这条横幅消息似乎是全局状态的一部分,因此商店将是一个很好的解决方案。仅当您需要为页面上的不同组件树设置不同的横幅时才需要上下文。
像这样的东西会起作用:
// src/lib/message.js
import { writable } from 'svelte/store';
export default writable('Default message');
<!-- src/routes/__layout.svelte -->
<script>
import message from '$lib/message';
</script>
<slot />
<p>{$message}</p>
<!-- 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>
所以我想不出一种方法来从 <slot>
.
__layout
变量传递一个变量
我尝试了一些方法,在插槽上使用 bind:
或 let:
,但它不起作用。我得到 'myvar' is not a valid binding
或 <slot> cannot have directives
.
我也尝试导出或不导出布局上的变量,但我真的无法让它工作...
这是我的:
<!-- __layout.svelte -->
<script>
export let myvar = undefined;
</script>
<main>
<slot myvar={myvar}></slot>
<p>Layout myvar: {myvar}</p> <!-- << This will stay undefined -->
</main>
<!-- mypage.svelte -->
<script>
import MyComponent from "$lib/my_component.svelte";
export let myvar;
let a_list_of_things = [1,2,3,4]
</script>
<main>
{#each a_list_of_things as thing}
<MyComponent bind:myvar={myvar} thing={thing}/> <!-- The variable is binded here -->
{/each}
<p>mypage myvar: {myvar}</p> <!-- << This will get the good value -->
</main>
<!-- my_component.svelte -->
<script>
import IconButton from '@smui/icon-button'
export let myvar;
export let thing;
</script>
<div>
<IconButton class="material-icons" on:click={() => myvar='something'} >
autorenew
</IconButton> <!-- << We change the value on:click here -->
</div>
所以主要目标是在布局级别上有一个等同于 bind:myvar=myvar
的对象(对于 <slot></slot>
.
我尝试理解 documentation 关于它的内容,但没有成功,它似乎更多地是关于组件槽而不是布局槽。
我发现
为什么我需要这个?
所以我的应用程序结构如下:
__layout
├─ header (menu)
├─ my_page (<slot>)
│ └ my_component (many)
└ interactive banner
这样显示:
[ Header Menu ]
Content of the page
- component 1
- component 2
- component n
[ Current component: 2 ] << Updated when click on an elem in the component
component
定义交互式横幅应显示的内容。同样点击interactive banner
可以改变components
我在下面给出了一个带有命名插槽的示例,也未命名 ->
在Slot.svelte
<script>
let content ='lorem'
</script>
<slot name='named-slot' >
{content}
</slot>
在父组件中
<script>
import Data from './Slot.svelte'
let newData=' new content'
</script>
<Data>
<svelte:fragment slot='named-slot' let:newData={content}>
{newData}
</svelte:fragment>
</Data>
以及未命名插槽的示例 ->
在Slot.svelte
<script>
let content ='lorem'
</script>
<slot >
{content}
</slot>
在父组件中
<script>
import Data from './Slot.svelte'
let newData=' new content'
</script>
<Data let:newData={content}>
{newData}
</Data>
由于这条横幅消息似乎是全局状态的一部分,因此商店将是一个很好的解决方案。仅当您需要为页面上的不同组件树设置不同的横幅时才需要上下文。
像这样的东西会起作用:
// src/lib/message.js
import { writable } from 'svelte/store';
export default writable('Default message');
<!-- src/routes/__layout.svelte -->
<script>
import message from '$lib/message';
</script>
<slot />
<p>{$message}</p>
<!-- 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>