Svelte:在模块中引用自我以供使用

Svelte: Reference to self for use in modules

我在Popup.svelte中有一个简单的弹出组件:

<script>
    let hidden = true;
</script>

<button on:click={() => hidden = !hidden}> Pop </button>
<div class:hidden> Extra Content </div>

<style>
    .hidden { display: none; }
</style>

我的应用程序中显示了多个:

<script>
    import Popup from './Popup.svelte';
</script>

<div> <Popup /> </div>
<div> <Popup /> </div>
<div> <Popup /> </div>

我想在单击时隐藏组件级别的其他弹出窗口,这意味着任何时候只能看到一个弹出窗口。我认为 svelte module contexts 会适合,但我无法添加对 self 的引用,我可以使用它为其他人调用 say setHidden 函数。

<script>
    import {onMount} from 'svelte';
    let hidden = true;
    export const setHidden = value => hidden = value;
    const toggleHidden = () => {
        if (hidden === true) { // transition to false
            hideOthers();
        }
        hidden = !hidden
    }
    onMount(() => elements.add(self);
</script>

<script context="module">
    const elements = new Set();
    const hideOthers = () => elements.forEach(e => e.setHidden(true))
</script>

游乐场here

上下文方法是一个很好的方法,但是您可以添加组件的 setHidden 函数,而不是向元素添加 self

<script context="module">
    const elements = new Set();
    const hideOthers = () => elements.forEach(hide => hide())
</script>

<script>
  onMount(() => elements.add(setHidden))
</script>

对于简单的隐藏内容,@Stephane 的回答很有效。但是如果有多个函数,您可以将它们添加到一个对象中并将其添加到模块上下文中。

您还可以在使用 Map 而不是 set 遍历所有元素时检查您是否使用当前实例。我正在使用对象键来获取对每个实例的唯一引用。

<script context="module">
    const elements = new Map();
    const hideOthers = () => Array.from(elements.entries()).forEach(([k, funcs]) => {
          funcs.setHidden(true)
          // if (k === key)
          // true for current instance
          // do something in the current instance
    });
</script>

<script>
    let key = {};
    let hidden = true; ​
   ​ const funcs = {
        setHidden: value => hidden = value,
        setSomething: value => something = value,
        setElse: value => else = value
    }
    ​onMount(() => elements.set(key, funcs))
</script>