<svelte:head>、<svelte:element> 与 <svelte:options>
本教程共 50 篇 · 第 31 篇 · 更新于 2026-08-05 · 约 6 分钟阅读
31. svelte:head、svelte:element 与 svelte:options
本节目标:学会用 svelte:head 管理 HTML head 标签,用 svelte:element 渲染动态标签名,用 svelte:options 设置组件编译选项。
svelte:head 管理 head 标签
网页的 <head> 标签里放着 <title>、<meta> 等信息。Svelte 让你在组件里直接管理这些内容。
<svelte:head>
<title>我的页面标题</title>
<meta name="description" content="这是页面的 SEO 描述" />
</svelte:head>
<div>页面内容</div>
在服务端渲染时,<svelte:head> 里的内容会被单独提取到 HTML 的 <head> 标签中。在客户端,Svelte 会动态操作 document.head。
动态 head 内容
head 内容可以是动态的,绑定到变量上。
<script>
let { title, description } = $props();
</script>
<svelte:head>
<title>{title}</title>
<meta name="description" content={description} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
</svelte:head>
<article>
<h1>{title}</h1>
<p>{description}</p>
</article>
Tip在 SvelteKit 中,你通常会在
+page.svelte或+layout.svelte里用<svelte:head>来设置每个页面的标题和 SEO 信息。
实战:动态页面标题
<script>
let count = $state(0);
let pageTitle = $derived(`计数器 (${count}) - 我的网站`);
</script>
<svelte:head>
<title>{pageTitle}</title>
</svelte:head>
<h1>计数器</h1>
<button onclick={() => count += 1}>
点击:{count}
</button>
每次点击按钮,浏览器标签页上的标题都会实时更新。
svelte:element 动态标签
有时候你在写代码时不知道该渲染什么 HTML 标签。比如你做一个富文本编辑器,标签类型来自用户配置或 CMS 数据。
<svelte:element> 让你用一个变量来指定标签名。
<script>
let tag = $state('h1');
</script>
<input bind:value={tag} placeholder="输入标签名" />
<!-- this 决定渲染什么标签 -->
<svelte:element this={tag}>
这段文字的标签是 {tag}
</svelte:element>
this 属性的值可以是任意有效的 HTML 标签名字符串。当 this 为 null 或 undefined 时,元素和子内容都不会渲染。
动态标签加属性
<svelte:element> 上可以加任何属性和事件,跟普通元素一样。
<script>
let tag = $state('button');
function handleClick() {
console.log('被点击了');
}
</script>
<select bind:value={tag}>
<option value="button">button</option>
<option value="a">a</option>
<option value="div">div</option>
</select>
<svelte:element
this={tag}
onclick={handleClick}
style="padding: 10px; background: #eee; cursor: pointer;"
>
点我(标签是 {tag})
</svelte:element>
void 元素的限制
空元素(void element)如 <br>、<hr>、<img> 不能有子内容。如果给 <svelte:element> 设置了空元素标签名又加了子内容,开发模式下会报错。
<script>
let tag = $state('hr');
</script>
<!-- 会报错:hr 不能有子元素 -->
<svelte:element this={tag}>
这段文字不能出现在 hr 里
</svelte:element>
Note
<svelte:element>只支持bind:this绑定,不支持其他bind:绑定,因为 Svelte 的内置绑定需要知道具体的元素类型。
SVG 命名空间
如果 <svelte:element> 在 SVG 上下文中使用,Svelte 会自动推断命名空间。如果推断不了,可以手动指定 xmlns 属性。
<svelte:element this={tag} xmlns="http://www.w3.org/2000/svg" />
svelte:options 组件选项
<svelte:options> 让你为单个组件设置编译器选项。它必须是自闭合的,放在组件顶层。
<svelte:options customElement="my-custom-element" />
可用选项
| 选项 | 说明 |
|---|---|
runes={true} | 强制组件使用 Runes 模式 |
runes={false} | 强制组件使用旧版模式 |
namespace="..." | 组件使用的命名空间:html(默认)、svg、mathml |
customElement={...} | 编译为自定义元素的选项 |
css="injected" | 样式内联注入而非提取到外部文件 |
runes 模式控制
<!-- 强制使用 Runes 模式 -->
<svelte:options runes={true} />
<script>
let count = $state(0);
</script>
<button onclick={() => count += 1}>{count}</button>
Note在 Svelte 5 中,只要组件里用了任何 rune(如
$state、$props),就会自动进入 Runes 模式。runes={true}主要用于强制没有使用 rune 的组件也进入 Runes 模式。
自定义元素编译
<svelte:options customElement="my-button" />
<script>
let { label } = $props();
</script>
<button>{label}</button>
这样这个组件就被编译成一个名为 my-button 的自定义元素,可以在任何地方使用 <my-button> 标签。
命名空间
当组件用于 SVG 或 MathML 上下文时,需要设置命名空间。
<svelte:options namespace="svg" />
<circle cx="50" cy="50" r="40" fill="red" />
css 注入
默认情况下 Svelte 会把组件样式提取出来。如果你希望样式内联注入(比如做独立分发的组件),可以设置 css="injected"。
<svelte:options css="injected" />
<div class="widget">独立组件</div>
<style>
.widget {
padding: 10px;
background: #f0f0f0;
}
</style>
已废弃的选项
Svelte 4 还有一些选项,在 Svelte 5 的 Runes 模式下已废弃:
| 废弃选项 | 旧版作用 |
|---|---|
immutable={true} | 数据不可变,编译器做引用相等检查 |
accessors={true} | 为组件 props 添加 getter/setter |
Note这些选项在 Runes 模式下不生效。如果你在迁移旧代码时看到它们,可以安全删除。
本节回顾
<svelte:head>在组件中管理 HTML head 内容,支持动态绑定<svelte:element this={tag}>用变量指定标签名,支持任意属性和事件<svelte:element>的this为 null/undefined 时不渲染,不支持除bind:this外的绑定<svelte:options>设置单个组件的编译选项- 常用选项:
runes、namespace、customElement、css immutable和accessors在 Runes 模式下已废弃