首页 / Svelte 5 入门教程 / use: 指令(Actions)

Svelte 5 入门教程

use: 指令(Actions)

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

SvelteSvelte 5use指令ActionsDOM操作

本节目标:理解什么是 Action,学会编写 Action 函数封装 DOM 操作,掌握参数传递和清理机制,实现 clickOutside 和 tooltip 等实用功能。

Action 是什么

Action 是一种函数,在元素被挂载到 DOM 时自动调用。你用它来封装那些需要直接操作 DOM 的逻辑。

打个比方,Action 就像给元素配了个贴身管家。元素一挂载,管家就到位,帮你处理各种杂事。元素卸载时,管家也会做好收尾工作。

<script>
	function myaction(node) {
		// node 就是挂载的 DOM 元素
		console.log('元素已挂载', node);

		$effect(() => {
			// 设置逻辑放这里

			return () => {
				// 清理逻辑放这里
			};
		});
	}
</script>

<div use:myaction>我有一个 Action</div>

最简单的 Action

来写一个让元素挂载后变色的 Action。

<script>
	function highlight(node) {
		$effect(() => {
			node.style.backgroundColor = 'yellow';
			node.style.padding = '2px 4px';

			return () => {
				// 元素卸载时恢复
				node.style.backgroundColor = '';
				node.style.padding = '';
			};
		});
	}
</script>

<p use:highlight>这段文字会被高亮</p>

传参数

Action 可以接收参数。用 use:action={参数} 的语法传入。

<script>
	let color = $state('lightblue');

	function setColor(node, color) {
		$effect(() => {
			node.style.backgroundColor = color;

			return () => {
				node.style.backgroundColor = '';
			};
		});
	}
</script>

<!-- 传入参数 -->
<div use:setColor={color}>背景色跟着变量变</div>

<input bind:value={color} />
Note

Action 函数只在元素挂载时调用一次。参数变化不会重新调用 Action,但 $effect 内部的逻辑会响应参数变化。

实战:clickOutside 点击外部

一个经典场景:弹出一个下拉菜单,点击外面时自动关闭。

<script>
	let showMenu = $state(false);

	function clickOutside(node, callback) {
		$effect(() => {
			function handleClick(event) {
				// 如果点击的不是当前元素及其子元素
				if (!node.contains(event.target)) {
					callback();
				}
			}

			document.addEventListener('click', handleClick, true);

			return () => {
				document.removeEventListener('click', handleClick, true);
			};
		});
	}
</script>

<div use:clickOutside={() => showMenu = false}>
	<button onclick={() => showMenu = !showMenu}>菜单</button>

	{#if showMenu}
		<ul style="position: absolute; background: white; border: 1px solid #ccc;">
			<li>选项一</li>
			<li>选项二</li>
			<li>选项三</li>
		</ul>
	{/if}
</div>
Tip

clickOutside 是最常用的 Action 之一。你可以把它抽到一个单独的 .svelte.js 文件中复用。

实战:tooltip 提示

另一个常见场景:鼠标悬浮显示提示文字。

<script>
	function tooltip(node, text) {
		let tooltipEl;

		$effect(() => {
			function show() {
				tooltipEl = document.createElement('div');
				tooltipEl.textContent = text;
				tooltipEl.style.cssText = `
					position: absolute;
					background: black;
					color: white;
					padding: 4px 8px;
					border-radius: 4px;
					font-size: 12px;
					z-index: 9999;
				`;
				document.body.appendChild(tooltipEl);
			}

			function hide() {
				tooltipEl?.remove();
			}

			node.addEventListener('mouseenter', show);
			node.addEventListener('mouseleave', hide);

			return () => {
				node.removeEventListener('mouseenter', show);
				node.removeEventListener('mouseleave', hide);
				hide();
			};
		});
	}
</script>

<button use:tooltip={'这是一个提示'}>
	悬浮看提示
</button>

旧版返回值写法

在 Svelte 5 的 $effect rune 出现之前,Action 通过返回对象来管理更新和销毁。这种写法仍然支持,但推荐用 $effect

<script>
	// 旧写法(仍支持,但不推荐)
	function oldAction(node, param) {
		// 挂载时执行

		return {
			update(newParam) {
				// 参数变化时执行
			},
			destroy() {
				// 元素卸载时执行
			}
		};
	}
</script>

<div use:oldAction={'参数'}>旧写法</div>
对比项$effect 写法(推荐)旧写法 update/destroy
参数更新自动响应需要手动写 update
清理逻辑return 清理函数destroy 方法
Runes 兼容完全兼容兼容但不推荐

Action 的类型标注

用 TypeScript 时,可以用 Action 类型来标注。

<script lang="ts">
	import type { Action } from 'svelte/action';

	const clickOutside: Action<HTMLElement, () => void> = (node, callback) => {
		$effect(() => {
			function handleClick(event: MouseEvent) {
				if (!node.contains(event.target as Node)) {
					callback?.();
				}
			}

			document.addEventListener('click', handleClick, true);
			return () => document.removeEventListener('click', handleClick, true);
		});
	};
</script>

<div use:clickOutside={() => console.log('点了外面')}>
	点外面试试
</div>
Note

在 Svelte 5.29 及以上版本,官方推荐使用 @attach 附件(Attachments)替代 use: 指令,因为附件更灵活、更可组合。但 use: 仍然完全可用,大量现有代码也在使用。

本节回顾

  • Action 是元素挂载时自动调用的函数,用于封装 DOM 操作
  • use:actionName 绑定,用 use:actionName={参数} 传参
  • 推荐在 Action 内部用 $effect 管理副作用和清理逻辑
  • clickOutsidetooltip 是两个最经典的 Action 应用场景
  • 旧版 update/destroy 返回值写法仍支持,但推荐用 $effect
  • TypeScript 中可用 Action 类型进行标注