如何在 svelte 3 中强制渲染?

use*_*222 5 svelte

我有一个带有输入字段的表单。当我键入 (keyup)Enter键时,必须清除这些字段之一。我知道我可以将此字段作为受控字段处理(意味着监听keyup并维护该字段的副本),或者使用双向绑定,但在我的用例中我不能做后者,我宁愿不做前者。因此,我的问题是,如何强制渲染 Svelte 组件?

通常,表单显示为<Component field="value" />,用户修改字段并单击Enter键,我想app.set(field, value)字段重置为value,即使在 Svelte 看来,该field属性没有改变。那可能吗?

我尝试不成功的转变在于更新Svelte 组件的属性,希望当 时app.set(field, value),Svelte 将看到该field属性的两个不同值并更新组件。但这似乎不起作用:

<script>

  const watchForEnter = ev => {
    if (ev.keyCode === 13) {
      ev.preventDefault();
      const formData = new FormData(ev.target.closest("form"));
      const tag = formData.get("tag");
      dispatch({ [ADDED_TAG]: tag });
    }
  };

  const updateCurrentTag = ev => {
    currentTag = new FormData(ev.target.closest("form")).get("tag");
    console.log(`currentTag!`, currentTag)
  }

</script>

        <form>
            <fieldset class="form-group">
              <input
                name="tag"
                class="form-control"
                type="text"
                placeholder="Enter tags"
                on:input={updateCurrentTag}
                value={currentTag}
                on:keyup={watchForEnter} />
            </fieldset>
        </form>
Run Code Online (Sandbox Code Playgroud)

rix*_*ixo 0

我不明白你给出的示例中的所有内容,但你的问题的一般答案是,在 Svelte 中,你应该尽量避免需要自己触发更新的情况。

在大多数情况下,可以使您的组件更具声明性,并更好地利用反应性(特别是反应性语句),以便 Svelte 在需要时进行渲染。

但是,对于不可能的情况,作为解决方法,您可以滥用块的密钥{#each ...}来强制 Svelte 重新创建通常会重用的组件。

例如:

<script>
  export let allItems
  export let currentCategory

  $: items = allItems.filter(x => x.category === currentCategory)
</script>

{#each [items] as todos (currentCategory)}
  <Todos {todos} />
{/each}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,请参阅另一个答案(我从中复制了上面的示例)。

另请参阅此 REPL,它展示了如何将这种 hack 实现到可重用组件中,以便消费者获得更清晰的语法。

而且,为了完整起见,还有刚刚出现的这个问题,并且要求正是这个功能。

  • 我在 npm 上发布了一个实现此解决方法的组件:https://github.com/rixo/svelte-key (2认同)