首页 / Svelte 5 入门教程 / 事件处理

Svelte 5 入门教程

事件处理

本教程共 50 篇 · 第 18 篇 · 更新于 2026-08-05 · 约 6 分钟阅读

SvelteSvelte 5事件处理onclick事件修饰符

本节目标:学会在 Svelte 5 中用 onclick 属性式写法监听 DOM 事件,掌握事件对象、内联处理器和事件修饰符的用法,了解与 Svelte 4 的差异。

属性式事件:onclick 而非 on:click

Svelte 5 做了一个很大的改变:事件处理不再是指令,而是普通的属性。

什么意思呢?在 Svelte 4 里,你监听点击事件要写 on:click,中间有个冒号。Svelte 5 把它简化成了 onclick,跟原生 HTML 的写法一模一样。

<script>
	let count = $state(0);
</script>

<!-- Svelte 5 写法:事件就是一个属性 -->
<button onclick={() => count += 1}>
	点击次数:{count}
</button>

这个改动的好处是,事件跟 classhref 这些属性地位一样了。你可以用简写形式,也可以用展开语法。

<script>
	let count = $state(0);

	function onclick() {
		count += 1;
	}
</script>

<!-- 简写形式:变量名和属性名相同 -->
<button {onclick}>
	点击次数:{count}
</button>
Note

简写要求变量名和属性名完全一致。如果你的函数叫 handleClick,就不能简写,得写完整形式 onclick={handleClick}

事件属性是大小写敏感的。onclick 监听的是 click 事件,而 onClick 监听的是 Click 事件,两者完全不同。这让你可以监听名称中包含大写字母的自定义事件。

事件对象

事件处理函数会自动收到一个事件对象参数,跟原生 DOM 事件一模一样。

<script>
	function handleClick(event) {
		// event 就是原生的 MouseEvent
		console.log('点击坐标:', event.clientX, event.clientY);
	}
</script>

<button onclick={handleClick}>点我</button>

如果你用的是内联箭头函数,事件对象需要你手动接收。

<script>
	let lastX = $state(0);
</script>

<!-- 内联写法,event 需要手动写出来 -->
<button onclick={(event) => lastX = event.clientX}>
	记录 X 坐标:{lastX}
</button>

内联处理器

内联处理器就是在属性里直接写箭头函数。它的好处是可以直接访问外层变量,不需要额外定义函数。

<script>
	let name = $state('');

	function greet(greeting, event) {
		console.log(`${greeting},${name}!`);
		console.log('事件来源:', event.target);
	}
</script>

<input bind:value={name} placeholder="输入名字" />

<!-- 内联处理器可以传额外参数 -->
<button onclick={(e) => greet('你好', e)}>
	打招呼
</button>
Tip

Svelte 的内联处理器不会有性能损失。编译器会自动优化,不需要担心性能问题。

事件修饰符

在 Svelte 4 里,事件修饰符用 | 管道符来加,比如 on:click|preventDefault。Svelte 5 推荐你在函数里手动处理。

最常见的需求是阻止默认行为和阻止冒泡。

<script>
	function handleSubmit(event) {
		// 手动阻止默认行为
		event.preventDefault();
		console.log('表单已提交');
	}

	function handleClick(event) {
		// 手动阻止冒泡
		event.stopPropagation();
		console.log('只会触发一次');
	}
</script>

<form onsubmit={handleSubmit}>
	<button type="submit">提交</button>
</form>

<div onclick={() => console.log('外层 div')}>
	<button onclick={handleClick}>内层按钮</button>
</div>

不过如果你怀念 Svelte 4 的修饰符语法,在 on: 指令(旧语法)中仍然支持这些修饰符:

修饰符作用
preventDefault调用 event.preventDefault()
stopPropagation阻止事件冒泡
stopImmediatePropagation阻止同事件的其他监听器
passive提升触摸/滚轮事件性能
nonpassive显式设置 passive: false
capture在捕获阶段触发
once只触发一次
self仅当 target 是元素本身时触发
trusted仅当 event.isTrusted 为 true 时触发
<!-- Svelte 4 旧写法(仍然支持,但不推荐) -->
<form on:submit|preventDefault={handleSubmit}>
	<button type="submit">提交</button>
</form>
Note

在 Svelte 5 的 Runes 模式下,推荐使用 onclick 属性式写法,在函数体内手动处理 preventDefault 等逻辑。on: 指令仅作为迁移过渡使用。

多个事件监听器

同一个元素可以绑定多个相同类型的事件处理器,它们会按顺序执行。

<script>
	let count = $state(0);

	function increment() {
		count += 1;
	}

	function log(event) {
		console.log('事件对象:', event);
	}
</script>

<!-- 两个 click 处理器都会执行 -->
<button onclick={increment} onclick={log}>
	点击次数:{count}
</button>

事件委托

为了提升性能,Svelte 对部分事件使用了事件委托技术。具体来说,Svelte 会在应用根节点上挂一个监听器,统一处理这些事件。

被委托的事件包括:

  • clickdblclickcontextmenu
  • inputchangebeforeinput
  • keydownkeyup
  • mousedownmousemovemouseovermouseoutmouseup
  • pointerdownpointermovepointeroverpointeroutpointerup
  • touchstarttouchmovetouchend
  • focusinfocusout
Tip

如果你需要手动派发一个被委托的事件,记得设置 { bubbles: true },否则事件无法到达应用根节点。

时序问题

事件属性的触发时机有个细节你需要知道:事件处理器总是在绑定更新之后触发。

比如 oninput 总是在 bind:value 更新之后才执行。这意味着你在 oninput 里读到的已经是最新值。

<script>
	let text = $state('');

	function handleInput(event) {
		// 此时 text 已经是输入框的最新值
		console.log('绑定值:', text);
		console.log('事件值:', event.target.value);
	}
</script>

<!-- oninput 会在 bind:value 更新后触发 -->
<input bind:value={text} oninput={handleInput} />

与 Svelte 4 对照

对比项Svelte 4Svelte 5
事件绑定on:click={fn}onclick={fn}
修饰符on:click|preventDefault函数内手动 event.preventDefault()
简写不支持{onclick}(变量名需和属性名一致)
展开不支持{...eventProps}
组件事件createEventDispatcher回调 Props(下一章讲)
Note

如果你从 Svelte 4 迁移过来,on:click 语法仍然可用,但官方推荐使用 onclick 属性式写法。

本节回顾

  • Svelte 5 用 onclick 属性式写法替代了 Svelte 4 的 on:click 指令
  • 事件处理函数自动接收原生事件对象
  • 内联箭头函数写法没有性能损失,可以自由使用
  • 事件修饰符改为在函数体内手动处理(preventDefaultstopPropagation 等)
  • Svelte 对部分事件使用事件委托来优化性能
  • 事件处理器总是在绑定更新之后触发