首页 / Svelte 5 入门教程 / Svelte 组件文件结构

Svelte 5 入门教程

Svelte 组件文件结构

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

SvelteSvelte 5组件.svelte文件TypeScript

本节目标:掌握 .svelte 文件的三段式结构,理解每种脚本标签的用途,学会用 .svelte.js 模块文件共享响应式逻辑。学完你能看懂并编写规范的 Svelte 组件。

三段式结构

Svelte 组件写在 .svelte 文件里,本质是 HTML 的超集。一个完整的组件包含三个部分:

<!--- file: MyComponent.svelte --->
<script module>
	// 模块级逻辑(不常用)
</script>

<script>
	// 实例级逻辑(常用)
</script>

<!-- 标记(HTML 模板) -->

<style>
	/* 样式 */
</style>

三个部分都是可选的。一个只有模板的 .svelte 文件也是合法组件。

<script> 实例脚本

<script> 标签里的代码在每个组件实例创建时执行一次。这里声明的变量可以在模板中直接使用:

<script>
	let name = 'Svelte';
	let count = 0;

	function handleClick() {
		count++;
	}
</script>

<h1>Hello {name}!</h1>
<button onclick={handleClick}>点击次数:{count}</button>

<script> 中,除了普通 JavaScript,你还可以使用 Runes(如 $state$derived$props 等)来声明响应式状态和组件属性。Runes 是 Svelte 5 的核心特性,后面几章会详细讲。

用 TypeScript

加上 lang="ts" 属性,就能在脚本里写 TypeScript:

<script lang="ts">
	let count: number = $state(0);
	let name: string = 'Svelte';

	function add(a: number, b: number): number {
		return a + b;
	}
</script>
Tip

推荐使用 TypeScript。类型提示能在编码时帮你发现错误,Svelte 的 VS Code 插件对此有完整支持。

<script module> 模块脚本

<script module> 标签里的代码在模块首次加载时执行一次,而不是每个组件实例都执行。所有实例共享同一份模块级变量。

<script module>
	let total = 0;

	// 可以 export,外部文件能导入
	export function getTotal() {
		return total;
	}
</script>

<script>
	total += 1;
	console.log(`这个组件已被实例化 ${total} 次`);
</script>

这里有两个要点:

  • 模块脚本的变量能被实例脚本访问,反过来不行
  • 模块脚本里可以 export,导出的内容能被其他文件 import
Note

在 Svelte 4 中,模块脚本的写法是 <script context="module">。Svelte 5 改成了 <script module>,更简洁。实际开发中模块脚本用得不多,大多数逻辑放在实例脚本里就行。

<style> 样式

<style> 标签里的 CSS 默认是作用域隔离的(scoped),只影响当前组件的元素:

<p>这段文字是棕色的</p>

<style>
	p {
		/* 只会影响当前组件的 <p> */
		color: burlywood;
	}
</style>

Svelte 编译时会自动给元素加上唯一的 class 哈希值,确保样式不泄漏到其他组件。

模板标记

<script><style> 之间的部分就是模板,写的是标准 HTML 加上 Svelte 的扩展语法:

<div class="card">
	<h2>{title}</h2>
	<p>{description}</p>
</div>

模板里可以用 {} 插入 JavaScript 表达式,可以用 {#if}{#each} 等控制流标签。这些会在后面的章节详细讲。

组件命名约定

Svelte 组件文件用大驼峰命名(PascalCase),如 MyComponent.svelteUserCard.svelte

在模板中使用组件时,标签名首字母必须大写,这样 Svelte 才能区分它是组件而不是普通 HTML 标签:

<script>
	import Widget from './Widget.svelte';
	import myStuff from './myStuff.js'; // 普通模块
</script>

<div>
	<Widget />        <!-- 大写开头 = 组件 -->
	<my.stuff />      <!-- 点号开头 = 组件 -->
	<div></div>       <!-- 小写开头 = HTML 元素 -->
</div>
Tip

约定俗成:HTML 元素全小写(divspan),Svelte 组件首字母大写(WidgetUserCard)。这条规则帮你一眼区分组件和原生标签。

.svelte.js / .svelte.ts 模块文件

除了 .svelte 文件,Svelte 5 还支持 .svelte.js.svelte.ts 文件。它们和普通的 .js/.ts 模块一样,但有一个关键区别:可以在里面使用 Runes

这让你能提取可复用的响应式逻辑,在多个组件间共享:

//--- file: counter.svelte.ts ---
export function createCounter(initial: number = 0) {
	let count = $state(initial);

	function increment() {
		count++;
	}

	function reset() {
		count = initial;
	}

	return {
		get count() {
			return count;
		},
		increment,
		reset
	};
}

在组件中使用:

<script lang="ts">
	import { createCounter } from './counter.svelte.ts';

	const counter = createCounter(10);
</script>

<button onclick={counter.increment}>
	计数:{counter.count}
</button>
Note

.svelte.js 文件是 Svelte 5 新增的概念,在 Svelte 4 中不存在。它是实现”组合式逻辑复用”的关键工具,类似于 Vue 3 的 Composables 或 React 的自定义 Hooks。

三种文件对比

文件类型用途能用 Runes能写模板
.svelte组件
.svelte.js / .svelte.ts响应式逻辑模块不能
.js / .ts普通模块不能不能

本节回顾

  • .svelte 文件是三段式结构:<script>(逻辑)、模板(HTML)、<style>(样式)
  • <script> 是实例级,每次组件创建时执行;<script module> 是模块级,只执行一次
  • lang="ts" 即可使用 TypeScript
  • <style> 默认 scoped,样式只作用于当前组件
  • 组件文件用大驼峰命名,使用时首字母大写区分于 HTML 元素
  • .svelte.js / .svelte.ts 模块文件支持 Runes,用于共享响应式逻辑