我有一个简单地隐藏内容的应用程序Hidden.svelte:
<script>
export let shown = false;
</script>
<svelte:options accessors={true}/>
{#if shown}
<slot/>
{/if}
Run Code Online (Sandbox Code Playgroud)
在 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>
Run Code Online (Sandbox Code Playgroud)
但是,虽然我可以这样做,但我不能这样on:click={child.shown = true}做:
{#if child.shown}
External message!
{/if}
Run Code Online (Sandbox Code Playgroud)
显然,我也不能这样做:
<div class:shown={child.shown}>Child component is shown</div>
Run Code Online (Sandbox Code Playgroud)
我想,这就是所有的,因为它在安装之前渲染,但是我所有的努力与玩onMount和$:失败
它可以以某种方式实现吗?谢谢
编辑
对不起,大家,我已经尝试尽可能简单地举一个例子,并且做了一个完全不能反映我最初问题的例子,但是,从技术上讲,得到了正确的答案
所以,问题是,父级App.svelte没有反映child.shown直接在内部进行的更改Hidden.svelte
@ThomasHennes 建议使用商店来解决这个问题,但是,如果我做对了,这是单个应用程序实例的好方法,因此,对于那些感兴趣的人,我最终会遇到常规事件:
https://svelte.dev/repl/f467fe36446444f09a2a7633b1faa6a1?version=3.20.1
编辑 2
在接受的答案中解决了真正的问题
我想你可能忽略了一个更直接的可能性: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}
Run Code Online (Sandbox Code Playgroud)
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}
Run Code Online (Sandbox Code Playgroud)