Solid.js 最新官方文档翻译(6)—— 组件事件处理程序

前言

Solid.js,一个比 React 更 react 的框架。每一个使用 React 的同学,你可以不使用,但不应该不了解

目前 Solid.js 发布了最新的官方文档,但却缺少对应的中文文档。为了帮助大家学习 Solid.js,故有此系列。

我同时搭建了 Solid.js 最新的中文文档站点:solid.yayujs.com ,欢迎勘误。

虽说是翻译,但个人并不喜欢严格遵守原文,为了保证中文阅读流畅,会删减部分语句,对难懂的部分也会另做补充解释,希望能给大家带来一个好的中文学习体验。

欢迎围观朋友圈、加入低调务实优秀中国好青年前端社群,一个人走得快,一群人走得远。

事件处理程序

事件处理程序是指为响应浏览器中发生的特定事件而调用的函数,例如当用户单击某个元素时。

Solid 提供了两种向浏览器添加事件监听器的方法:

  • [on:__](https://docs.solidjs.com/reference/jsx-attributes/on): 向 element 添加事件监听器。这也称为本机事件(native event)
  • [on__](https://docs.solidjs.com/reference/jsx-attributes/on_): 将事件监听器添加到 document 并将其分派到 element 。这也被称为委托事件(delegated event)。

委托事件流经组件树,通过复用常用事件节省一些资源。本机事件流经 DOM 树,可以提供对事件行为的更多控制。

使用事件

要添加事件处理程序,在事件名称前加上 onon:前缀:

tsx 复制代码
// delegated event
<button onClick={handleClick}>Click me</button>

// native event
<div on:scroll={handleScroll}>... very long text ...</div>

委托事件不区分大小写 ,因此在 Solid 中使用委托事件处理程序可以使用驼峰式或全部小写形式编写。请注意,虽然委托事件可以用两种方式编写,但本机事件区分大小写

tsx 复制代码
<button onclick={handleClick}>Click me</button>

对于其他事件,例如自定义事件或您不希望被代理的事件,使用 on:属性将原样添加事件处理器,这就是事件处理器区分大小写的原因:

tsx 复制代码
<button on:Custom-Event={handleClick}>Click me</button>

对于使用 on:的标准或自定义事件的类型,TypeScript 页面有一个关于事件处理器的部分。

绑定事件

要优化事件处理程序,您可以传递一个数组替代原本的函数作为事件处理程序,此时传递到数组的第二个条目将作为处理程序的第一个参数:

tsx 复制代码
const handler = (data, event) => {
    console.log("Data:", data, "Event:", event);
};

<button onClick={[handler, "Hello!"]}>Click Me</button>;

在这个例子中 ,点击按钮时,Hello!字符串将作为 handler 函数中的 data 参数传递。

通过这种方式绑定事件,Solid 避免了使用 JavaScript bind 方法造成的额外闭包开销。

动态处理程序

事件处理程序不是响应式系统的一部分,如果您将处理程序作为信号传递,它将不会响应信号的更改。换句话说,事件不会动态更新,并且绑定也不是响应式。这是因为添加和删除监听器是一项资源密集型人物。

由于事件处理程序的调用方法类似于标准函数,因为你可以将它们设计为在需要时调用响应式资源。

在下面的例子中,handleClick表示 props 具有调用任何函数的灵活性。因为不需要这些函数是响应式的:

tsx 复制代码
<div onClick={() => props.handleClick?.()} />

事件委托

Solid 没有将事件监听器添加到每个单独的元素,而是通过 on__ 的形式使用合成事件委托 。在这种方法中,事件监听器将添加到 document 元素,并在相关元素冒泡时将事件分派给它们。

通过将事件监听器的数量保持在最低限度,可以更有效地捕获事件。当处理大量元素(例如表格或列表)时特别有用。

clickinputkeydown 等受支持的事件只是以这种方式优化的几个示例。要查看完整列表,请参阅下面的委托事件列表

如果您需要将事件监听器添加到 Solid 的事件委托不支持的元素(例如自定义元素,%20you%20can%20use%20the%20on:__中的自定义事件),则可以使用 on:__ 形式。

tsx 复制代码
<div on:customEvent={handleCustomEvent} />

事件委托注意事项

虽然事件委派提供了一些性能增强,但也需要权衡。

事件委托是为通过 JSX 树而不是 DOM 树传播事件而设计的。这可能与之前对事件如何运行和流动的预期不同。

需要记住的一些事情包括:

  • 委托事件监听器针对每个事件类型都添加一次,并处理该类型的所有未来事件。这意味着即使添加事件监听器的元素及其处理程序被删除,委托事件监听器仍保持活动状态。例如,如果 div 监听 mousemove 并随后被删除,mousemove 事件仍将分派到 document,以防还有另一个元素也在监听鼠标移动。
tsx 复制代码
<div onMouseMove={handleCustomEvent} />

注意:

对于不经常发生的事件,本机事件是更好的解决方案。由于这些事件发生在特定情况下,因此它们不会从通过事件委托获得的性能改进中受益。

tsx 复制代码
<div on:mousemove={handleCustomEvent} />
  • event.stopPropagation() 无法按预期工作,因为事件添加到 document 而不是 element

对于此类情况,建议使用本机事件。例如在接下来的例子中,使用本机事件将阻止事件到达 div native 处理程序,而委托事件则不能。

tsx 复制代码
onMount(() => {
  ref.addEventListener("click", () => {
    console.log("div native");
  });
});
<div ref={ref}>
  <button
    onClick={(event) => {
      event.stopPropagation();
      console.log("button");
    }}
  >
    button
  </button>
</div>;

输出结果为:

tsx 复制代码
// Button clicked
div native
button

您可以在 Solid Playground 中查看此示例

但如果将 button 改为使用本机事件:

tsx 复制代码
// ...
<button
  on:click={(event) => {
    event.stopPropagation();
    console.log("button");
  }}
>
  button
</button>
// ...

输出结果为:

tsx 复制代码
// Button clicked
button

您可以在 Solid Playground 中查看此示例。

  • Portals 按照组件树而不是 DOM 树传播事件,这使得它们更易于使用。这意味着当 Portal 添加到 body 时,任何事件都会传播到 container
tsx 复制代码
<div class="container" onInput={() => console.log("portal key press")}>
  <Portal mount={document.body}>
    <input onInput={() => console.log("input key press")} />
  </Portal>
</div>

注意:

onChangeonInput 事件根据其原生行为工作:

  • onInput 将在值更改后立即触发

  • <input> 字段中,onChange 仅在字段失去焦点后触发。

委托事件列表

您可以在我们的源代码中查看此列表(请参阅 DelegatedEvents )。

系列目录

  1. Solid.js 最新官方文档翻译(1)------ 介绍与快速开始
  2. Solid.js 最新官方文档翻译(2)------ 响应式介绍
  3. Solid.js 最新官方文档翻译(3)------ JSX
  4. Solid.js 最新官方文档翻译(4)------ 组件基础
  5. Solid.js 最新官方文档翻译(5)------ 组件 Class 与 Style
相关推荐
余生H25 分钟前
前端的Python应用指南(一):快速构建 Web 服务器 - Flask vs Node.js 对比
服务器·前端·python
白瑕1 小时前
[JavaScript] 我该怎么去写一个canvas游戏
前端·javascript
m0_748248941 小时前
前端篇-Content-Type 详解
前端
m0_748255021 小时前
新手参加2025年CTF大赛——Web题目的基本解题流程
前端·网络·安全
憨憨小江1 小时前
Vue3 基础记录
前端
SANG嘻嘻嘻1 小时前
ES6中的map和set
前端·javascript·es6
fantasy_arch1 小时前
CPU性能优化--前端优化
前端·性能优化
粥里有勺糖2 小时前
视野修炼第114期 | 2024JS现状调查结果
前端·javascript·github
程序视点2 小时前
【安全漏洞】Vue UI库Vant组件遭恶意投毒,字节RspacK也中招!请紧急修复!
前端·vue.js·ui
szx的开发笔记2 小时前
JS实现在线预览HTML文件
开发语言·javascript·html