Svelte - 绑定子组件的 属性
Svelte - bind on child component's property
我有一个应用程序可以简单地隐藏内容 Hidden.svelte
:
<script>
export let shown = false;
</script>
<svelte:options accessors={true}/>
{#if shown}
<slot/>
{/if}
父级一切正常 App.svelte
:
<script>
import Hidden from 'Hidden';
let child;
</script>
<Hidden bind:this={child}>
Content
</Hidden>
<button on:click={() => child.shown = true}>Show</button>
但是,虽然我可以做到这一点on:click={child.shown = true}
,但我不能做到这一点:
{#if child.shown}
External message!
{/if}
显然,我也做不到:
<div class:shown={child.shown}>Child component is shown</div>
我想,这都是因为它在安装之前呈现,但我所有尝试玩 onMount
和 $:
都失败了
能以某种方式实现吗?感谢
编辑
抱歉,各位,我已经尝试制作尽可能简单的示例,并制作了一个根本无法反映我最初问题的示例,但是,从技术上讲,我得到了正确的答案
所以,问题是,父级 App.svelte
没有反映直接在 Hidden.svelte
中进行的 child.shown
更改
@ThomasHennes 建议使用商店来解决这个问题,但是,如果我做对了,这对单个应用程序实例来说是个好方法,所以,对于那些感兴趣的人,我最终得到了定期事件:
https://svelte.dev/repl/f467fe36446444f09a2a7633b1faa6a1?version=3.20.1
编辑 2
实际问题已在接受的答案中解决
您需要做的就是测试 child
和 child.shown
:
{#if child && child.shown}
External message!
{/if}
<div class:shown={!child || !child.shown}>Child component is shown</div>
见https://svelte.dev/repl/10f1e41e4fc3465d81bba5efcff84c4a?version=3.20.1
您还可以使用反应值来管理组合条件:
$: childShown = child && child.shown
然后使用 childShown
或 !childShown
有条件地显示内容。
我想你可能忽略了一个更直接的可能性:bind:property.
虽然 bind:this
对于抓取 DOM 元素非常有用,但我倾向于认为它是组件的最后解决方案。
如果您设法让 Svelte 知道需要跟踪什么,那么生成的代码很可能会比您自己使用事件或其他任何东西更高效。部分是因为它将使用已经存在于您的应用程序中的 Svelte 运行时代码,部分是因为 Svelte 会生成经过认真优化的更改跟踪代码,这将很难在保持人性化的同时编写所有代码。部分原因是您的更改跟踪目标会更窄。
此外,您将获得更简洁的代码。更多由机器处理的样板意味着更多的人可以用于实际逻辑。
所以...如果您对道具的变化值感兴趣,可以绑定到道具。这是我的做法。
Hidden.svelte
<script>
export let shown = false // <= you can bind to this!
export const show = () => { shown = !shown } // <= you can bind to this, too!
</script>
<button on:click={show}>Child's button</button>
{#if shown}
<slot/>
{/if}
App.svelte
<script>
import Hidden from './Hidden.svelte'
let shown
let show
</script>
<button on:click={show}>Parent's button</button>
<Hidden bind:shown bind:show>
<div>Hidden content</div>
</Hidden>
{#if shown}
<div>Hidden child is shown!</div>
{/if}
我有一个应用程序可以简单地隐藏内容 Hidden.svelte
:
<script>
export let shown = false;
</script>
<svelte:options accessors={true}/>
{#if shown}
<slot/>
{/if}
父级一切正常 App.svelte
:
<script>
import Hidden from 'Hidden';
let child;
</script>
<Hidden bind:this={child}>
Content
</Hidden>
<button on:click={() => child.shown = true}>Show</button>
但是,虽然我可以做到这一点on:click={child.shown = true}
,但我不能做到这一点:
{#if child.shown}
External message!
{/if}
显然,我也做不到:
<div class:shown={child.shown}>Child component is shown</div>
我想,这都是因为它在安装之前呈现,但我所有尝试玩 onMount
和 $:
都失败了
能以某种方式实现吗?感谢
编辑
抱歉,各位,我已经尝试制作尽可能简单的示例,并制作了一个根本无法反映我最初问题的示例,但是,从技术上讲,我得到了正确的答案
所以,问题是,父级 App.svelte
没有反映直接在 Hidden.svelte
child.shown
更改
@ThomasHennes 建议使用商店来解决这个问题,但是,如果我做对了,这对单个应用程序实例来说是个好方法,所以,对于那些感兴趣的人,我最终得到了定期事件:
https://svelte.dev/repl/f467fe36446444f09a2a7633b1faa6a1?version=3.20.1
编辑 2
实际问题已在接受的答案中解决
您需要做的就是测试 child
和 child.shown
:
{#if child && child.shown}
External message!
{/if}
<div class:shown={!child || !child.shown}>Child component is shown</div>
见https://svelte.dev/repl/10f1e41e4fc3465d81bba5efcff84c4a?version=3.20.1
您还可以使用反应值来管理组合条件:
$: childShown = child && child.shown
然后使用 childShown
或 !childShown
有条件地显示内容。
我想你可能忽略了一个更直接的可能性:bind:property.
虽然 bind:this
对于抓取 DOM 元素非常有用,但我倾向于认为它是组件的最后解决方案。
如果您设法让 Svelte 知道需要跟踪什么,那么生成的代码很可能会比您自己使用事件或其他任何东西更高效。部分是因为它将使用已经存在于您的应用程序中的 Svelte 运行时代码,部分是因为 Svelte 会生成经过认真优化的更改跟踪代码,这将很难在保持人性化的同时编写所有代码。部分原因是您的更改跟踪目标会更窄。
此外,您将获得更简洁的代码。更多由机器处理的样板意味着更多的人可以用于实际逻辑。
所以...如果您对道具的变化值感兴趣,可以绑定到道具。这是我的做法。
Hidden.svelte
<script>
export let shown = false // <= you can bind to this!
export const show = () => { shown = !shown } // <= you can bind to this, too!
</script>
<button on:click={show}>Child's button</button>
{#if shown}
<slot/>
{/if}
App.svelte
<script>
import Hidden from './Hidden.svelte'
let shown
let show
</script>
<button on:click={show}>Parent's button</button>
<Hidden bind:shown bind:show>
<div>Hidden content</div>
</Hidden>
{#if shown}
<div>Hidden child is shown!</div>
{/if}