首页 / Svelte 5 入门教程 / @html、@const 与 @debug

Svelte 5 入门教程

@html、@const 与 @debug

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

SvelteSvelte 5模板语法@html@const@debug

本节目标:掌握 {@html}、{@const}、{@debug} 三个特殊模板标签的用法和注意事项。学完你能在模板中安全渲染 HTML、声明局部常量、调试响应式状态。

{@html}:渲染原始 HTML

基本用法

默认情况下,{} 插值会自动转义 HTML 标签。如果你需要渲染原始 HTML,用 {@html}

<script>
	let content = '<strong>加粗文字</strong>';
</script>

<!-- 转义:显示原始标签 -->
<p>{content}</p>
<!-- 输出:<strong>加粗文字</strong> -->

<!-- 原始 HTML:渲染为加粗 -->
<p>{@html content}</p>
<!-- 输出:<strong>加粗文字</strong>(文字加粗显示) -->

安全警告

Warning

{@html} 不会对内容做任何转义。如果你渲染用户输入的 HTML,可能导致 XSS 攻击。永远不要用 {@html} 渲染不可信的内容。

<script>
	// 假设这是用户提交的内容
	let userInput = '<img src=x onerror="alert(\'XSS攻击\')">';
</script>

<!-- ❌ 危险!可能执行恶意代码 -->
<div>{@html userInput}</div>

<!-- ✅ 安全:普通插值会转义 -->
<div>{userInput}</div>

如果确实需要渲染用户提供的 HTML,先用专门的库(如 DOMPurify)做净化:

<script>
	import DOMPurify from 'dompurify';

	let userInput = '<script>alert("xss")<\/script>文字内容';
	let safe = $derived(DOMPurify.sanitize(userInput));
</script>

<div>{@html safe}</div>

样式限制

{@html} 渲染的内容对 Svelte 的 scoped 样式是「不可见」的。也就是说,组件 <style> 里的选择器不会作用到 {@html} 插入的元素上:

<!-- ❌ 不起作用:a 和 img 的样式不会应用到 @html 内容 -->
<article>
	{@html content}
</article>

<style>
	article {
		a { color: hotpink }
		img { width: 100% }
	}
</style>

:global() 修饰符解决,把要穿透作用域的选择器包进括号:

<!-- ✅ 用 :global() 让样式穿透到 @html 渲染的内容 -->
<style>
	article :global(a) { color: hotpink }
	article :global(img) { width: 100% }
</style>
Note

{@html} 渲染的内容必须是完整的 HTML 片段。不能把标签拆开写(如 {@html '<div>'} + 内容 + {@html '</div>'}),也不能在里面写 Svelte 语法。

{@const}:声明局部常量

基本用法

{@const} 在模板中声明一个局部常量,只能在块内部使用:

<script>
	let boxes = [
		{ width: 10, height: 10 },
		{ width: 15, height: 20 },
		{ width: 5, height: 8 }
	];
</script>

{#each boxes as box}
	{@const area = box.width * box.height}
	<p>{box.width} × {box.height} = {area}</p>
{/each}

输出:

10 × 10 = 100
15 × 20 = 300
5 × 8 = 40

使用位置限制

{@const} 只能作为以下内容的直接子级:

  • {#if ...}
  • {#each ...}
  • {#snippet ...}
  • <Component /> 标签
  • <svelte:boundary>
<!-- ✅ 在 each 块中 -->
{#each items as item}
	{@const total = item.price * item.qty}
	<p>{total}</p>
{/each}

<!-- ✅ 在 if 块中 -->
{#if condition}
	{@const label = '条件为真'}
	<p>{label}</p>
{/if}

<!-- ✅ 在组件标签中 -->
<div>
	{@const className = isActive ? 'active' : 'inactive'}
	<ChildComponent class={className} />
</div>

<!-- ❌ 不能在顶层直接使用 -->
{@const x = 1}  <!-- 编译错误 -->
Tip

{@const} 适合在模板里做简单的中间计算,避免在 <script> 中写一堆 $derived。如果计算逻辑复杂或需要响应式更新,还是应该用 $derived

与声明标签的关系

Note

在 Svelte 5.56+ 中,{@const} 被视为旧语法。推荐使用声明标签 {const x = value} 替代。下一章会详细介绍声明标签。目前两者都能使用,{const}{@const} 的进化版,使用位置更灵活。

{@debug}:调试断点

基本用法

{@debug} 是比 console.log 更强的调试工具。它在指定变量变化时自动打印值,并在开发者工具打开时暂停执行:

<script>
	let user = $state({
		firstname: 'Ada',
		lastname: 'Lovelace'
	});
</script>

{@debug user}

<h1>Hello {user.firstname}!</h1>
<input bind:value={user.firstname} />

每次 user 变化时(比如在输入框中输入),控制台会打印 user 的当前值,并触发 debugger 断点。

语法规则

{@debug} 接受逗号分隔的变量名列表,不能是表达式:

<!-- ✅ 合法 -->
{@debug user}
{@debug user1, user2, user3}
{@debug}  <!-- 无参数:任何状态变化都触发 -->

<!-- ❌ 编译错误 -->
{@debug user.firstname}      <!-- 不能是属性访问 -->
{@debug myArray[0]}          <!-- 不能是数组索引 -->
{@debug !isReady}            <!-- 不能是表达式 -->
{@debug typeof user === 'object'}  <!-- 不能是表达式 -->
Note

{@debug} 是开发调试工具,生产构建时会自动移除,不影响线上性能。建议在排查响应式问题时临时使用,不要长期留在代码中。

调试 vs console.log

对比项{@debug}console.log
触发时机变量变化时自动触发只在执行时打印一次
断点自动触发 debugger
表达式支持只支持变量名任意表达式
适用位置模板中<script>
适合场景排查响应式更新问题一次性日志

三个标签对比

标签作用生产环境
{@html}渲染原始 HTML保留
{@const}声明局部常量保留(推荐用 {const} 替代)
{@debug}调试断点自动移除

本节回顾

  • {@html 内容} 渲染原始 HTML,但有 XSS 风险,不可信内容必须先净化
  • {@html} 内容不受 scoped 样式影响,需用 :global() 穿透
  • {@const 变量 = 值} 在块内声明局部常量,简化中间计算
  • {@const} 只能用在 if/each/snippet/组件标签内部
  • {@debug 变量} 在变量变化时打印并暂停,只接受变量名不接受表达式
  • {@debug} 生产环境自动移除,适合临时调试
  • Svelte 5.56+ 推荐用声明标签 {const} 替代 {@const}