什么是 Svelte
Svelte 在 JavaScript 框架中占据了非常独特的一席之地。React、Vue 是运行时库,而 Svelte 是编译器。它在构建时把组件编译为纯 JavaScript,因此浏览器无需接收额外的框架代码。 Svelte 最鲜明的特点是不使用虚拟 DOM。状态发生变化时,Svelte 在编译时生成的代码会直接更新 DOM。因此可以做到非常轻量、高速的 UI。本文讲解的是 Svelte 5 与 Inertia v3 的组合。Laravel 13 的启动套件默认使用这一组合。
Svelte 5 的 runes
Svelte 5(2024 年发布)引入了名为 Runes 的新响应式系统。使用$state、$derived、$effect 等特殊函数(runes)来声明响应式状态。相比 Svelte 4 之前的隐式响应式,它更加显式、更易预测。
在 Laravel 中的定位
历史
相较 Vue 和 React,Svelte 与 Laravel 的关系非常新,被官方启动套件采纳才是它的第一次官方支持。 2026 年的 Laravel 13 在启动套件中正式加入 Svelte,让 Svelte 成为 Laravel 生态中的官方前端选项之一。它和 Vue、React 平起平坐,可以在laravel new 的交互式提示中选择。
对不少 Laravel 用户来说 Svelte 还不算熟悉,但它以编译带来的轻量包体积和简洁语法著称,从 Vue 或 React 迁移过来,你可能会惊讶“居然要写这么少”。
当前主流:Inertia × Svelte
当前 Laravel 中使用 Svelte 的主流方式就是 Inertia × Svelte。Inertia 让你不必设计 API,就能直接从 Laravel 控制器把数据传给 Svelte 组件,实现“现代单体”架构。搭建
通过启动套件(推荐)
新项目最省事的方式就是使用启动套件。inertiajs/inertia-laravel(服务端适配器)@inertiajs/svelte(客户端适配器)svelte+@sveltejs/vite-plugin-svelte(Svelte 5 本体及 Vite 插件)- TypeScript +
svelte-check - Tailwind CSS + shadcn-svelte 组件库
HandleInertiaRequests中间件- 登录 / 注册等认证页面(已用 Inertia + Svelte + TypeScript 实现)
手动安装
在已有项目中引入时,分别安装服务端和客户端。vite.config.ts 里加上 Svelte 插件和 Inertia Vite 插件。
resources/js/app.ts 里启动 Inertia 应用。@inertiajs/vite 插件会负责页面的自动解析和挂载,入口写得非常精简。
手动安装的详细步骤(根模板设置、中间件注册等)请参考 Inertia 官方文档。
目录结构
启动套件把 Svelte 页面组件放在resources/js/pages/ 下。
Inertia::render('posts/Index', [...]) 时对应的就是 resources/js/pages/posts/Index.svelte。
Svelte 文件的基本结构
.svelte 文件由 <script>、模板、<style> 三块组成。
<style> 默认作用域受限,不用担心类名冲突。
模板语法
变量展开与表达式
在模板中用{} 嵌入 JavaScript 的值或表达式。
{#if} —— 条件分支
v-if / v-else,或 React 中的三元运算符。
{#each} —— 列表渲染
(post.id) 是键,用于高效的差异更新。相当于 Vue 的 v-for 或 React 的 Array.map()。
bind: —— 双向绑定
用 bind:value 可以让表单元素的值和响应式变量双向同步。
v-model。React 里通常需要手写 onChange,Svelte 里用 bind: 就能声明式表达。
页面组件基础
Inertia 的页面组件就是普通的 Svelte 组件。从 Laravel 控制器传来的数据会以 props 的形式接收。控制器
Svelte 页面组件
在 Svelte 5 里用$props() rune 接收 props。
$props() 接收 props,就可以在模板里直接使用控制器传来的数据。无需定义 REST API。
Link 组件
使用 @inertiajs/svelte 提供的 <Link> 组件,页面跳转通过 XHR 完成,避免整页重载。
<a> 一样,但幕后 Inertia 只替换页面组件,体验接近 SPA。
Form 组件
@inertiajs/svelte 提供的 <Form> 组件是启动套件认证页面推荐的表单提交样式。通过 props 指定 action 和 method,内部用 {#snippet} 写内容。
基本用法
{#snippet children({ errors, processing })} 是 Svelte 的 snippet 语法,用来向组件传入内容块(相当于 Vue 的 slot 或 React 的 render props)。errors 和 processing 由 Form 组件自动计算并传入。表单字段用 HTML 原生的 name 属性,而不是 bind:value,让浏览器的标准表单数据采集照常工作。
启动套件的模式
启动套件通过 Wayfinder 把路由当作对象管理。store.form() 会返回包含路由对象的 action 与 method 的对象,直接 spread 到 <Form>。
resetOnSuccess 中列出的字段会在提交成功后自动重置。密码等提交完希望清空的字段可以列在这里。
不用 Wayfinder 时,直接传
action="/login" 就能达到同样效果。useForm hook
表单处理使用 @inertiajs/svelte 的 useForm hook,可以简洁实现状态管理、提交、校验错误展示。
控制器侧
Svelte 表单组件
useForm 返回对象的主要属性:
校验返回错误时,
useForm 会保留已输入内容并显示错误。配合 bind:value,可以实现顺畅的表单体验。
共享数据(Shared Data)
所有页面都需要的公共数据(登录中的用户信息、闪存消息等)可以在HandleInertiaRequests 中间件的 share() 方法中定义。
usePage() 访问共享数据。
共享数据会包含在每次请求中,建议只保留必要的最少数据。用
fn() 惰性求值时,只有真正访问时才求值。Svelte 5 的响应式(runes)
Inertia × Svelte 开发中你需要了解的 Svelte 5 runes。$state —— 响应式状态
$state 声明的变量会自动变成响应式,值变化时 DOM 会自动更新。相当于 Vue 的 ref 或 React 的 useState,但不用访问 .value,直接赋值就能更新状态。
$derived —— 派生值
$derived 会在依赖值变化时自动重新计算。相当于 Vue 的 computed 或 React 的 useMemo。
$effect —— 副作用处理
$effect 会在其依赖的 $state 变化时执行。相当于 React 的 useEffect,但不需要显式写依赖数组,使用到的 $state 会被自动追踪。
shadcn-svelte 组件
启动套件里已经集成了 shadcn-svelte。它与 React 的 shadcn/ui 设计思路相同,是一个可以把代码拷贝到项目里自由定制的组件库。添加组件
resources/js/components/ui/。
用法
npx shadcn-svelte@latest add 添加。
总结
Svelte 与 Laravel 组合起来,特别是通过 Inertia 采用“现代单体”结构时,会显现出真正的实力。基于编译器的设计让包体积很小,runes 语法让响应式表达更加明确、易懂。
用 Inertia × Svelte,你可以拿到 Laravel 后端的简洁与 Svelte 精简写法双重加成的开发体验。用启动套件创建项目,连认证页面在内都是现成的,可以马上开始开发。
Inertia.js 官方文档
Inertia v3 的完整功能请参考官方文档。