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

StencilJS中二次渲染组件覆盖首个组件输入框自动聚焦问题

问题根因

  • 浏览器的页面焦点是全局唯一资源,同一时间仅能有一个输入类元素持有焦点,你当前给所有search-input组件都默认配置了加载完成后自动执行聚焦逻辑,后触发聚焦的组件自然会抢占之前组件的焦点。
  • Stencil的自定义组件是异步加载渲染的,componentDidLoad生命周期的触发顺序和DOM标签的书写顺序没有必然绑定,所以每次最后拿到焦点的组件也不固定。

解决方案

最合理的处理方式是给组件增加自动聚焦的开关属性,仅在显式声明需要聚焦的组件上开启该能力:

第一步:修改组件代码,增加autoFocus控制逻辑

import { Component, h, Prop, Event, EventEmitter, Method } from '@stencil/core';
@Component({
  tag: 'search-input',
  styleUrl: 'search-input.css',
  shadow: true,
})
export class SearchInput {
  private searchInput: HTMLInputElement;
  
  @Prop() value = "";
  
  @Prop() dataTestId!: string;
  
  @Prop() placeHolder: string = "Search";

  // 新增自动聚焦开关,默认关闭
  @Prop() autoFocus: boolean = false;
  
  @Event() clearSearch: EventEmitter;
  
  @Event() searchRequest: EventEmitter;

  // 可选:对外暴露手动聚焦方法,满足上层自定义触发聚焦的需求
  @Method()
  async setFocus() {
    this.searchInput?.focus();
  }

  protected componentDidLoad() {
    // 只有autoFocus为true时才执行自动聚焦
    if (this.autoFocus) {
      this.searchInput.focus();
    }
  }

  render() {
    return (
      <div data-test-id={this.dataTestId} class="items-center flex bg-white border-solid rounded-sm border-gray-300 box-border text-xl border-1 pl-15 pr-12 py-9">
          <input
            type="text"
            ref={el => (this.searchInput = el as HTMLInputElement)}
            data-test-id={`${this.dataTestId}-search-input`}
            class="focus:outline-none border-0 flex-grow w-full pl-15"
            value={this.value}
            placeholder={this.placeHolder}
          />
      </div>
    );
  }
}

第二步:使用时按需开启自动聚焦

比如你需要第一个搜索框默认聚焦,就只给第一个组件加auto-focus属性即可:

<!DOCTYPE html>
<html dir="ltr" lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=5.0" />
    <title>Stencil Component Starter</title>

    <script type="module" src="/build/testing.esm.js"></script>
    <script nomodule src="/build/testing.js"></script>
  </head>
  <body>
    <!-- 仅给需要默认聚焦的组件加auto-focus属性 -->
    <search-input auto-focus data-test-id="test-two" place-holder="Search" value=""></search-input>
    <search-input data-test-id="test-three" place-holder="Search" value=""></search-input>
  </body>
</html>

如果有动态切换聚焦的需求,你可以获取对应search-input的DOM实例,调用暴露的setFocus方法手动触发聚焦即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 05:45:01