这个 `dispatch()` 被完全忽略了。为什么?

问题描述 投票:0回答:1

我为未调用 Svelte 调度的问题创建了重现:

重现步骤

  1. 打开复制

  2. 打开浏览器控制台

  3. 使用链接进入“关于”页面

  4. 我应该看到消息:“handleInput”,但我没有看到

相关代码

<script>
    import Select from 'svelte-select';
    import { createEventDispatcher } from 'svelte';

    export let value = undefined;
    export let id = undefined;
    
    const dispatch = createEventDispatcher();
    
    let result;

    let items = [
        { value: 'one', label: 'One' },
        { value: 'two', label: 'Two' },
        { value: 'three', label: 'Three' },
    ];

    $: if (id !== undefined) {
        result = id;
    }

    $: if (result != undefined) {
        value = { value: 'custom', label: 'Custom' };
        console.log("this should dispatch!")
        dispatch('input', value);
        console.log("is it dispatched?")
    }
</script>

<Select {value} {items} on:change on:input />

dispatch('input', value)
完全被忽略。

为什么?

javascript svelte svelte-select
1个回答
0
投票

复制步骤为:

  1. 导航至“关于”页面
  2. ✅ 观察handleInput 未记录到浏览器控制台(此操作成功失败)

您的反应式语句在

on:input
事件侦听器附加到
<Select>
组件之前触发。这可能是由于在 DOM(或组件标记)安装之前调用响应式语句,并且在组件安装之后附加事件侦听器。

您的

setTimeout
代码之所以有效,是因为它添加了一个微任务,该微任务可能在事件侦听器设置后注册;因此,当其回调函数触发时,您的
on:input
侦听器将收到调度的事件。同样,使用
await tick()
使您的代码可以出于同样的原因工作:

async function dispatchEvent () {
  value = { value: 'custom', label: 'Custom' };
  console.log("this should dispatch!")

  // wait for all microtasks to complete before continuing
  await tick() 
  dispatch('input', value);
  console.log("is it dispatched?")
}

$: if (result != undefined) {
  dispatchEvent()
}

话虽如此,有许多反应性的言论是很难遵循的。我建议重构以在您的

CustomSelect.svelte
中使用事件侦听器,它可以与事件转发结合使用:

<Select on:input={internalInputHandler} on:input on:change />
<!--    ^ handle input                  ^ forward input -->

我还建议使用自定义名称调度事件,而不是覆盖本机事件名称;这样你就可以单独处理它们并期望原生

InputEvent
on:input
。您可以为已调度的事件命名
input--id
:

<!-- Component.svelte -->
<script>
  function handler() {
    dispatch('input:component', { some: 'detail' })
  }
</script>

<!-- +page.svelte -->
<Select on:input--id={doSomething} on:input={doSomethingElse} />
© www.soinside.com 2019 - 2024. All rights reserved.