Svelte 介绍
约 1411 字大约 5 分钟
2025-11-15
组件
在 Svelte 中,应用由 一个或多个组件组成。
组件是构建 UI 的基本单元,它是一个 可复用、自包含 的代码块,通常包含:
- HTML —— 结构
- CSS —— 样式
- JavaScript/TypeScript —— 逻辑
这些内容全部写在一个 .svelte 文件中,因此 Svelte 文件看起来非常直观、可读性强。
<script>
// JS/TS 逻辑
</script>
<style>
/* CSS 样式 */
</style>
<!-- HTML 模板 -->
<main>
{表达式}
</main>比如 App.svelte 是项目中的根组件。
组件的逻辑写在 <script> 标签内(支持 lang="ts" 使用 TypeScript):
<script lang="ts">
let name = 'Svelte';
</script>这里我们声明了一个变量 name,之后可以在模板中直接使用。
插值表达式
Svelte 使用大括号 {} 来将 JavaScript 变量插入到 HTML 标记中:
<h1>Hello {name}!</h1>效果会渲染为:
Hello Svelte!你也可以在大括号中写任意 JavaScript 表达式,例如:
<h1>Hello {name.toUpperCase()}!</h1>渲染为:
Hello SVELTE!表达式尽量保持简单,虽然可以写复杂逻辑,但推荐只放简单表达式,复杂逻辑写在 <script> 中会更清晰。
这种数据绑定的特点
- 插值
{}中可以直接使用 JavaScript - 数据驱动模板渲染
- 无需
.value、useState()等特殊语法 - 变量变化时,Svelte 会自动更新 DOM(内部由编译器优化)
属性绑定
在 Svelte 中,花括号 {} 并不只用于文本插值,它们同样可以用于 动态绑定 HTML 属性。
例如,为 <img> 添加动态的 src:
<img src={src} />这意味着当 src 变量变化时,图片资源会自动更新。
你可能会看到这样的提示:
<img> element should have an alt attributeSvelte 内置了 a11y 检查器,会自动提示你是否编写了对某些用户不友好的标记,例如:
<img>缺少alt<button>中没有文本<a>没有href- 标签语义使用不正确
这是为了确保应用能被所有用户访问,包括:
- 使用屏幕阅读器的视力障碍者
- 低带宽网络环境
- 弱硬件设备
- 依赖键盘导航的用户
在 <img> 中添加 alt 属性即可解决上面的问题:
<img src={src} alt="A man dances." />属性同样支持 JavaScript 表达式,比如字符拼接等
<img src={src} alt="{name} dances." />其中 " {name} dances. " 会自动变成实际的字符串,例如变量 name = 'Tom',渲染为:
Tom dances.属性简写
如果属性名与变量同名,例如:
<img src={src} />Svelte 提供属性简写语法:
<img {src} alt="{name} dances." />这会自动解读为:
src={src}Vue 也有类似语法,比如 :src="src",而 Svelte 更加简洁。
组件样式
就像普通的 HTML 一样,你可以在 Svelte 组件中编写 <style> 标签,为当前组件添加样式。
<p>This is a paragraph.</p>
<style>
p {
color: goldenrod;
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>这段样式只会应用到 当前组件内部的 <p> 标签。
Svelte 的一大特点是:组件内的样式自动是 scoped 的,它不会影响组件外的元素。
举例来说:
- 你在
App.svelte里写的<p>样式 - 不会影响
Header.svelte、Footer.svelte或其他地方的<p>标签
这是由 Svelte 编译器在构建时自动处理的。
在 Svelte 中使用 Scss / Less:
<style lang="scss">
.container {
color: red;
.nested {
font-size: 20px;
}
}
</style>组件嵌套
随着应用规模增长,不可能把所有逻辑都写在一个 .svelte 文件里。因此,Svelte 和其他现代框架一样,允许我们把 UI 拆分成多个独立组件,并在需要的地方导入和使用它们。
首先,在 App.svelte 顶部添加一个 <script> 标签,从本地文件导入组件:
<script lang="ts">
import Nested from './Nested.svelte';
</script>然后,就可以像使用普通 HTML 标签一样将它插入到模板中:
<p>This is a paragraph.</p>
<Nested />运行后,Nested.svelte 的渲染内容就会出现在对应位置。
即使 Nested.svelte 内也包含 <p> 元素,App.svelte 中的局部样式也不会影响它。
在 Svelte 中,组件通常使用 大写开头(PascalCase) 的名字,例如:
App.svelteNested.svelteUserCard.svelteProfileHeader.svelte
这样做是为了区分自定义组件与原生 HTML 标签(<div>、<p>…)
渲染 HTML
在 Svelte 中,模板中的字符串内容默认会以纯文本(textContent) 方式插入,这种行为可以防止 HTML 被误解析,也自然避免了 XSS 的风险。
例如:
<script>
let text = "<strong>Hello</strong>";
</script>
<p>{text}</p>页面上看到的是:
<strong>Hello</strong>而不是加粗的 “Hello”,这是安全默认值,字符串永远不会被当作 HTML 渲染。
某些场景下,你确实想要把字符串当作 HTML 展示。
例如:
- Markdown 转成的 HTML
- CMS(内容管理系统)的富文本内容
- 带有格式的文章片段
- 文档站点的 HTML 部分
在这种情况下,你可以使用 {@html ...} 指令:
<p>{@html string}</p>这会让 string 中的内容以真正的 HTML 插入 DOM。
Svelte 不会对 {@html ...} 的内容进行净化(sanitize)。
这意味着:
- 不会过滤
<script> - 不会过滤
onerror="..." - 不会过滤恶意事件处理函数
- 不会移除恶意 iframe 或链接
如果 你渲染用户提交的内容, 如:
- 评论区
- 用户 bio
- 富文本编辑器内容
- 论坛帖子
那么你必须手动进行 sanitize,否则会造成 跨站脚本攻击(XSS) 风险。
前端最常用的 HTML 清洗库 DOMPurify
npm install dompurify<script>
import DOMPurify from 'dompurify';
export let content;
// sanitize
const safe = DOMPurify.sanitize(content);
</script>
<div>{@html safe}</div>或者在 SvelteKit 中做服务器端净化。