Svelte 中部分 HTML 元素的条件渲染

Conditional rendering of a partial HTML element in Svelte

举个例子,假设我想为一组单选按钮创建一个组件:

<!-- App.Svelte --> 
<script>
    import Radio from './Radio.svelte';
</script>

<main>
    <Radio group={"stooges"}
        btns={["Larry", "Curly", "Moe", "Shep", "Joe", "Curley Joe"]}
        checked={"Curly"}
        disabled={["Moe", "Joe"]}
    />
</main>

无线电组组件的以下实现产生了正确的行为; Curly为预选; MoeJoe 变灰:

<!-- Radio.svelte -->
<script>
  export let group;
  export let btns;
  export let checked;
  export let disabled;
</script>

{#each btns as btn, idx}
  {#if btn === checked}
    {#if disabled.includes(btn)}
      <input type="radio" id={btn} value={btn} name={group} 
        checked disabled>
    {:else}
      <input type="radio" id={btn} value={btn} name={group} checked>
    {/if}
  {:else}
    {#if disabled.includes(btn)}
      <input type="radio" id={btn} value={btn} name={group} disabled>
    {:else}
      <input type="radio" id={btn} value={btn} name={group}>
    {/if}
  {/if}
  <label for={btn}>{btn}</label>
{/each}

这是无线电组组件的另一个实现,它更简洁,但不会编译:

<!-- Radio.svelte -->
<script>
  export let group;
  export let btns;
  export let checked;
  export let disabled;
</script>

{#each btns as btn, idx}
  <input type="radio" id={btn} value={btn} name={group}
    {#if btn === checked} checked {/if}
    {#if disabled.includes(btn)} disabled {/if} 
  >
  <label for={btn}>{btn}</label>
{/each}

编译器用消息 Expected } svelte(unexpected-token).

标记第一个 #if 语句的左大括号

我能想到的第二个实现中的错误的唯一原因是,与第一个实现不同,它在每个 if-else 分支上包含一个完整的 input 元素,第二个实现包含每个 if-else 分支上的 input 元素的一部分。但是,据我所知,Svelte 文档并未对此提出警告。

您不能在 element/component 标签内使用模板语法({#if}..{:else}..{/if}{#each}..{/each} 等)。

可以 ,但是,使 element/component 属性根据条件解析(这是您想要实现的):

{#each btns as btn, idx}
  <input
    type="radio"
    id={btn}
    value={btn}
    name={group}
    checked={btn === checked}
    disabled={disabled.includes(btn)}
  >
  <label for={btn}>{btn}</label>
{/each}

checkeddisabled会根据对应的语句求值赋值为true或false。

Demo REPL