首页 > 解决方案 > Svelte - 绑定子组件的属性

问题描述

我有一个简单地隐藏内容的应用程序Hidden.svelte

<script>
    export let shown = false;
</script>

<svelte:options accessors={true}/>

{#if shown}
    <slot/>
{/if}

在 parent 一切正常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级没有反映child.shown直接在内部进行的更改Hidden.svelte

@ThomasHennes 建议使用商店来解决这个问题,但是,如果我做对了,这是单个应用程序实例的好方法,所以,对于那些感兴趣的人,我最终会定期举办活动:

https://svelte.dev/repl/f467fe36446444f09a2a7633b1faa6a1?version=3.20.1

编辑 2

在接受的答案中解决了真正的问题

标签: javascriptsvelte

解决方案


我认为您可能忽略了一个更直接的可能性: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}

REPL


推荐阅读