You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Svelte中条件性使用use:registerFocus指令?

条件性使用Svelte Navigator的useFocus指令

问题背景

编辑:之前参考的包装方法无法适用于输入框聚焦的场景。

我正在使用svelte-navigator提供的useFocus()指令,实现了一个Input组件,希望通过isFocused属性控制单个Input实例获得焦点,其他实例则不聚焦。

核心问题:如何在Svelte中条件性启用use:registerFocus?

现有代码

Input.svelte:

<script>
  import { useFocus } from "svelte-navigator";
  const registerFocus = useFocus();
    
    // 如何让组件仅在isFocused为true时启用use:registerFocus?
    export let isFocused 
    export let value
    
    const maybeRegisterFocus = (element, isFocused) => {
        console.log(`为'${value}'注册焦点: ${isFocused}`)
        if (isFocused) {
       registerFocus(element);
    }
    return {
      update: (isFocused) => {
                console.log(`更新元素`, element)
        if (isFocused) {
          registerFocus(element);
        }
        return null;
      },
      destroy: () => {
        return null;
      },
    };
  };
</script>


<input use:maybeRegisterFocus={isFocused} value={value} />

App.svelte:

<script>
import { Router, Route } from "svelte-navigator";
import Input from "./Input.svelte"
</script>

<Router>
<Route>
    <h1>
        第一个输入框应该被聚焦。
        <Input isFocused={true} value="第一个输入框应该被聚焦"/>
    <Input isFocused={false} value="第二个输入框不应该被聚焦"/>

    </h1>
</Route>
</Router>

解决方案

你的包装指令没有处理useFocus返回的销毁函数,且状态切换时未清理旧的焦点注册。修改后的Input.svelte如下:

<script>
  import { useFocus } from "svelte-navigator";
  export let isFocused;
  export let value;

  const maybeRegisterFocus = (element, shouldFocus) => {
    let destroyFocus = null;

    const updateFocus = (newShouldFocus) => {
      // 先清理已有的焦点注册
      if (destroyFocus) {
        destroyFocus();
        destroyFocus = null;
      }
      // 需要聚焦时注册并保存销毁函数
      if (newShouldFocus) {
        destroyFocus = useFocus()(element);
      }
    };

    // 初始化执行一次
    updateFocus(shouldFocus);

    return {
      update: updateFocus,
      destroy: () => destroyFocus?.(),
    };
  };
</script>

<input use:maybeRegisterFocus={isFocused} {value} />

关键说明

  • 状态切换清理:每次isFocused变化时,先调用之前保存的销毁函数,取消旧的焦点绑定,避免多个实例同时注册焦点。
  • 动态注册:仅当isFocused为true时,才调用useFocus()生成指令并绑定到元素,同时保存销毁函数用于后续清理。
  • 组件销毁清理:组件销毁时自动调用销毁函数,确保资源被正确释放。

内容的提问来源于stack exchange,提问作者mikemaccana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:20:43