bind:this 模板引用
本教程共 50 篇 · 第 21 篇 · 更新于 2026-08-05 · 约 5 分钟阅读
本节目标:学会用 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.scrollTop、el.scrollTo() |
| 调用组件方法 | componentInstance.method() |
| 第三方库集成 | 把 DOM 节点传给第三方库初始化 |
本节回顾
bind:this可以获取 DOM 元素或组件实例的引用- 引用在组件挂载前是
undefined,必须在$effect或事件处理器中使用 - 组件实例通过
export function暴露方法,外部用bind:this调用 - 元素被
{#if}移除后,引用会变回undefined - 常见场景包括自动聚焦、Canvas 绘图、尺寸测量、第三方库集成