首页 / Svelte 5 入门教程 / bind:this 模板引用

Svelte 5 入门教程

bind:this 模板引用

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

SvelteSvelte 5bind:thisDOM引用模板引用

本节目标:学会用 bind:this 获取 DOM 元素和组件实例的引用,理解 null 检查的重要性,掌握自动聚焦、Canvas 绘图等常见场景。

获取 DOM 元素引用

有时候你需要直接操作 DOM 元素——比如让输入框获得焦点、获取 Canvas 的绘图上下文、测量元素位置。Svelte 提供了 bind:this 来帮你拿到 DOM 节点的引用。

打个比方,bind:this 就像给你家门牌号。别人有了门牌号就能直接找到你家,不用一层层问路。

<script>
	let canvas;

	$effect(() => {
		if (!canvas) return;
		const ctx = canvas.getContext('2d');
		ctx.fillStyle = 'red';
		ctx.fillRect(10, 10, 100, 100);
	});
</script>

<canvas bind:this={canvas} width="200" height="200"></canvas>

这段代码里,canvas 变量会指向那个 <canvas> DOM 元素。$effect 会在组件挂载后执行,此时 canvas 已经有值了,就可以调用 getContext 来绘图。

null 检查是必须的

bind:this 的值在组件挂载之前是 undefined。你不能在组件初始化阶段直接使用它。

<script>
	let input;

	// 错误!此时 input 还是 undefined
	// input.focus(); // 会报错

	// 正确做法:在 $effect 里使用
	$effect(() => {
		// 组件挂载后,input 才有值
		input?.focus();
	});
</script>

<input bind:this={input} placeholder="自动聚焦" />
Note

bind:this 的值在组件初始化时是 undefined,在组件挂载到 DOM 后才被赋值。你应该在 $effect 或事件处理器中读取它,而不是在 <script> 顶层直接使用。

自动聚焦示例

一个常见的场景:弹窗打开后,输入框自动获得焦点。

<script>
	let input;
	let showModal = $state(false);

	function openModal() {
		showModal = true;
	}

	$effect(() => {
		// 当弹窗显示时,自动聚焦输入框
		if (showModal && input) {
			input.focus();
		}
	});
</script>

<button onclick={openModal}>打开弹窗</button>

{#if showModal}
	<div class="modal">
		<input bind:this={input} placeholder="输入内容" />
		<button onclick={() => showModal = false}>关闭</button>
	</div>
{/if}

<style>
	.modal {
		padding: 20px;
		border: 1px solid #ccc;
		border-radius: 8px;
	}
</style>

在事件处理器中使用

在事件处理器中使用 bind:this 引用是最安全的,因为事件触发时元素一定已经挂载了。

<script>
	let div;

	function measure() {
		const rect = div.getBoundingClientRect();
		console.log('位置:', rect.left, rect.top);
		console.log('尺寸:', rect.width, rect.height);
	}
</script>

<div bind:this={div}>测量我</div>
<button onclick={measure}>测量元素</button>

获取组件实例引用

bind:this 不只能绑定 DOM 元素,还能绑定组件实例。这样你就可以从外部调用组件暴露的方法。

<!-- ShoppingCart.svelte -->
<script>
	let items = $state([]);

	// 暴露方法给外部调用
	export function empty() {
		items = [];
	}

	export function addItem(item) {
		items = [...items, item];
	}
</script>

<p>购物车有 {items.length} 件商品</p>
<!-- App.svelte -->
<script>
	import ShoppingCart from './ShoppingCart.svelte';

	let cart;

	function handleAdd() {
		cart.addItem('商品' + Date.now());
	}

	function handleEmpty() {
		cart.empty();
	}
</script>

<ShoppingCart bind:this={cart} />

<button onclick={handleAdd}>添加商品</button>
<button onclick={handleEmpty}>清空购物车</button>
Tip

子组件用 export function 暴露的方法,可以通过 bind:this 拿到的实例来调用。这是 Svelte 5 中组件命令式 API 的用法。

配合 if 块使用

当元素在 {#if} 块中时,元素被移除后 bind:this 的值会变回 undefined

<script>
	let el;
	let visible = $state(false);

	$effect(() => {
		if (el) {
			console.log('元素出现了');
		} else {
			console.log('元素消失了');
		}
	});
</script>

<button onclick={() => visible = !visible}>
	{visible ? '隐藏' : '显示'}
</button>

{#if visible}
	<div bind:this={el}>我出现又消失</div>
{/if}

使用场景总结

场景用法
自动聚焦input?.focus()
Canvas 绘图canvas.getContext('2d')
尺寸测量el.getBoundingClientRect()
滚动控制el.scrollTopel.scrollTo()
调用组件方法componentInstance.method()
第三方库集成把 DOM 节点传给第三方库初始化

本节回顾

  • bind:this 可以获取 DOM 元素或组件实例的引用
  • 引用在组件挂载前是 undefined,必须在 $effect 或事件处理器中使用
  • 组件实例通过 export function 暴露方法,外部用 bind:this 调用
  • 元素被 {#if} 移除后,引用会变回 undefined
  • 常见场景包括自动聚焦、Canvas 绘图、尺寸测量、第三方库集成