首页 > 解决方案 > 等待组件在自定义 svelte 指令中准备就绪

问题描述

我最近尝试编写一个自定义指令,该指令执行一些逻辑并将一个事件发送回它所使用的元素。

//svelte file
<div use:customDiective on:success={handleSuccess}>...</div>
// Custom directive
export const customDirective = node => {
    //some synchronous logic here

    node.dispatchEvent(new CustomEvent('success', node))
}

我发现,由于我的指令中的逻辑是同步的,它会在节点准备好捕获它之前调度新的自定义事件。我可以通过使用轻松解决它setTimeout(),但这似乎不是一个合适的解决方案。有什么方法可以让我使用生命周期方法或指令中的某些内容来确保组件已为分派事件做好准备?

标签: javascriptsveltesvelte-3

解决方案


您可以在操作中使用onMount生命周期函数:

// directive.js
import { onMount } from 'svelte';

export const customDirective = (node) => {
    onMount(() => {
        // other logic
        node.dispatchEvent(new CustomEvent('success', node));
    });     
}
<!-- App.svelte -->
<script>
    import { customDirective } from './directive.js';
    
    let isSuccess = false;
</script>

<div use:customDirective on:success={() => (isSuccess = true)}>{isSuccess}</div>

或者,如果您将指令放在on:指令之前use:,则将在运行操作之前设置事件侦听器。

<div on:success={() => (isSuccess = true)} use:customDirective>{isSuccess}</div>

您可以在生成的 Svelte 代码中看到指令的顺序:

// on: before use:
if (!mounted) {
    dispose = [
        listen(div, "success", /*success_handler*/ ctx[1]),
        action_destroyer(customDirective_action = customDirective.call(null, div))
    ];

    mounted = true;
}

// use: before on:
if (!mounted) {
    dispose = [
        action_destroyer(customDirective_action = customDirective.call(null, div)),
        listen(div, "success", /*success_handler*/ ctx[1])
    ];

    mounted = true;
}

推荐阅读