SvelteKit是我清单上最新的东西

2026年8月30日 learningsveltekit

SvelteKit是我清单上最新的框架,用它在博客的前端中建立东西是我在它中运送的真正第一件事。

在那之前大多是React:一个健身追踪器应用,一个MERN栈存储项目(Mongo、Express、React、Node、整个设置)。React的心智模型,组件,属性,状态,状态改变时重新呈现,花了我一段时间真正对其舒适。SvelteKit问你思考关于那个几乎没有相同的方式,这比我进入时期望的更令人困惑。

第一个bug是一个习惯,不是完全一个错误

我的非常第一个Svelte组件是一个小标签列表为管理员帖子编辑器,添加标签,看它出现在列表中。直接的,我想,来自React其中我做过这个确切的模式十几次。

<script>
	let tags = ["python", "learning"];

	function addTag(newTag) {
		tags.push(newTag);
	}
</script>

<button on:click={() => addTag("sveltekit")}>add tag</button>

{#each tags as tag}
	<span>{tag}</span>
{/each}

点击按钮。什么都没发生。不是一个错误,不是一个警告,列表只是默默地没有增长,这以某种方式比崩溃会更令人困惑。

我真的谷歌的东西

「svelte array push not updating ui」几乎立刻掉了确切的问题,它显然共同足够有它自己的解释在我清楚没有读过的Svelte文档中:Svelte的反应性被分配触发,不是通过变异。tags.push(newTag)原地变异现存的数组,而Svelte的编译器只知道重新呈现当它看到对tags的实际分配,某个像tags = tags或一个真正新的数组的东西。推将数组的内容改变而无需分配任何东西,所以没什么告诉Svelte再看。

<script>
	let tags = ["python", "learning"];

	function addTag(newTag) {
		tags = [...tags, newTag];
	}
</script>

一行不同。展开旧数组进一个新的,分配它回到tags,并现在每个添加是Svelte能看到的真实分配。在React这个确切的习惯被按惯例执行(setTags([...tags, newTag])只是怎样useState工作的,你不能通过变异规避它甚至如果你想到),所以我从未真实必须想关于为什么规则存在。Svelte让我直接变异,这感觉像少的仪式,直到它不工作并且我没有主意为什么。

没有虚拟DOM来推理关于

Svelte编译你的组件进代码那直接更新当一个值改变时的DOM。没有虚拟DOM差分步来精神上模型,这听起来像它应该让东西更简单并大多做,除外我持续寻找相当于useState那只在相同形状不在Svelte中的东西。

<script>
	let count = 0;
</script>

<button on:click={() => count += 1}>
	clicked {count} times
</button>

那是整个组件。分配给count是反应性触发。在React我会达到为useState出的习惯并且然后记得:对,只是重新分配变量,那是这里的整个机制,以及它是同样的规则那破坏了我的标签列表,只是这次因为+=工作正确的一个分配。

表单动作是实际的惊喜

来自React和Express,其中每个表单提交意味着为客户写一个fetch调用以及一个在服务器上的匹配API路由用手,SvelteKit的表单动作首先困惑了我因为它们看起来像他们代替了表单而不只是处理它的提交。我的第一个本能是对其战斗,以及构建React版本以外的习惯。

<!-- what I tried first, out of old habit -->
<script>
	async function handleSubmit(event) {
		event.preventDefault();
		const formData = new FormData(event.target);
		const res = await fetch("/api/comment", {
			method: "POST",
			body: JSON.stringify(Object.fromEntries(formData))
		});
	}
</script>

<form on:submit={handleSubmit}>
	<textarea name="body"></textarea>
	<button type="submit">Post comment</button>
</form>

技术上工作。但这意味着为API路由手写接收那个fetch,手写JSON解析,手写错误处理,所有的那个东西我已经在Express做,这SvelteKit实际上没有必要我自己做。

// +page.server.ts, the SvelteKit way
export const actions = {
	default: async ({ request }) => {
		const data = await request.formData();
		const body = data.get("body");
		if (!body) {
			return fail(400, { error: "comment cannot be empty" });
		}
		// save it
		return { success: true };
	}
};
<form method="POST">
	<textarea name="body"></textarea>
	<button type="submit">Post comment</button>
</form>

npm run dev picking up a real component for the first time

我关闭JavaScript在devtools出的好奇心,在普通method="POST"版本。表单仍然工作。那是时刻它点击适当:动作是处理器,而use:enhance是某件事你图层在稍后使其感觉更像一个单页应用,不是某件事表单需要在所有功能。我的MERN商店从未像那样工作。在那个应用杀死JS而且它是一个静态页面与死按钮,因为整个提交路径活着完全在客户上。

反应性陈述那默默地使用了一个陈旧的值

$:陈述是Svelte的另一个大的反应性机制,为从其他值计算的值,并且我有一旦被咬过通过假设他们再运行比他们实际做的更积极。

<script>
	let posts = [];
	let searchTerm = "";
	$: filtered = posts.filter((p) => p.title.includes(searchTerm));

	async function loadPosts() {
		const res = await fetch("/api/posts");
		posts = await res.json();
	}
</script>

这看起来罚款,并大多是。bug显示当我重新读loadPosts变异一个现存的数组与posts.push(...newPosts)为一个「加载更多」按钮而不是重新分配posts彻底,确切的同样变异与分配错误,只是穿一个不同的服装这个时间。filtered从未重新计算以后「加载更多」,因为Svelte的依赖性跟踪为$:手表为对posts的分配,同样规则象任何处处,以及一个变异的数组从未触发它。一旦我从标签列表的更早处识别了bug的形状,修复是相同的单行:重新分配而不是变异。

文件基础的路由为大约一天绊了我

来自Express,其中每个路由是一个代码的明确行(app.get("/posts/:slug", ...)),SvelteKit的文件基础的路由,其中一个文件夹取名[slug]在路由目录中只是变成动态路由,感觉像魔法我不信任第一天。我持续期待发现「真实」的路由器配置某处以及被混淆的它不存在,那文件夹结构真的是整个路由表。一旦它点击它感觉明显,同样方式重新分配规则做,但那天不信任它是真实的。

什么仍然绊我

反应性通过$:陈述对比普通重新分配不总是明确的我,确实什么时候Svelte再运行某些东西对比什么时候它不,尤其一旦依赖性埋了在函数调用内的而不是直接在陈述中参考。我有有一次它错误至少两次这个月在陈述中默默而不是错误一个陈旧值,这是一个坏的失败模式比React的「忘记它在依赖数组」版本。至少那个一通常只是再运行太经常而不是太很少,那是更和解的方向来错在。

svelte-check catching what I missed, before it caught nothing

我实际上在哪里降落在它

最新的东西在列表上,以及也目前我最喜欢的真实的写一天在天,变异bug旁边。无论那是框架或只是新的什么蜜月段,问我再次在六个月一旦我有它点击不管什么SvelteKit的相等物的反应式钩子头痛变成会。有一直总是一个。迄今我的只是相同教训两次,在标签列表以及然后在反应性陈述:改变值,不只改变什么它在地方指向。

0 条评论

登录 后即可评论。

登录

忘记密码?

还没有账号?