学习 Svelte:开始使用 Svelte 编写番茄工作法应用
本文最初发表于Barbarian Meets Coding。
Svelte是一个现代 Web 框架,它采用了一种新颖的方法来构建 Web 应用程序,将大部分工作从运行时转移到编译时。作为一个编译器优先的框架,Svelte 可以实现一些其他框架无法实现的非常有趣的功能,例如在运行时从应用程序中消失,或者允许以组件为中心的开发,使 HTML、JavaScript 和 CSS 以非常符合 Web 标准的方式共存于同一个 Svelte 文件中。
在本系列中,我们将跟随我第一次使用 Svelte 构建应用程序的过程。我将使用我的常用项目1来学习新的框架:一个番茄工作法应用程序,它比 TODO 列表稍微复杂一些,因为它至少包含几个需要相互交互的组件(一个计时器和一个任务列表)。
还没读过本系列的第一篇文章?那么你可能想看看,那里有很多资源可以帮助你开始使用 Svelte。
构建番茄工作法应用程序
对于不熟悉番茄工作法的人来说,可能需要先了解一下背景。我们先快速概括一下!
番茄工作法是一种旨在通过增强你的注意力并帮助你了解是什么让你分心来帮助你提高工作效率的技术。
本质上,这项技术要求你以25分钟不间断的专注时间(一个番茄时间单位)来完成任务。如果你分心了,或者有人打扰了你,你就写下分心的原因,然后从头开始。随着你对这项技术的掌握越来越熟练,你就会成为掌控分心的大师。你将能够保持更长时间的专注,完成更多的番茄时间,每天的效率也会更高。
如果你有兴趣,可以从这项技术的发明者那里了解更多关于它的信息。多年来,我发现这项技术特别有用,它能促使我在人生中最困难的时刻专注于手头的任务。
因此,支持这项技术的应用至少需要包含一个你一天内要完成的任务列表,以及一个番茄钟,用来标记你专注工作的时间段。之后,该应用还可以扩展,记录你经常分心的事情,追踪你一段时间内的进度等等。
在本系列文章中我们将重点开发MVP并实现任务列表和番茄钟。
开始吧!Wihoo!
Svelte 入门
开始使用 Svelte 最简单的方法是:
- 浏览svelte.dev 中的 Svelte 教程
- 在 svelte.dev 中对 Svelte REPL 进行修改
- 使用 svelte 模板从头创建应用程序
虽然我认为学习本教程对于学习 Svelte 的语法和可用功能非常有帮助,但我认为学习的最佳方式是在一个尽可能接近实际开发 Svelte 应用的环境中实际操作。你需要亲身实践解决问题才能真正学到东西。因此,我们将按照步骤 3 的步骤,利用 Svelte 模板来创建番茄工作法应用。
创建新项目
我们使用degit(一个项目脚手架工具,也是由 Svelte 的创建者 Rich Harris 编写的)生成一个新项目。输入:
$ npx degit sveltejs/template il-pomodoro
这会在目录中创建一个全新的 Svelte 项目il-pomodoro
。我们开始安装依赖项并运行开发服务器:
# Jump in
$ cd il-pomodoro
# Install the dependencies
$ npm install
# Run the development server
$ npm run dev
现在我们打开浏览器localhost:5000
看看我们得到了什么......
太棒了!Svelte,你好,世界!
设置你的编辑器
Svelte 是一个编译器优先的框架,它编译.svelte
代表 Svelte 组件的文件来构建 Web 应用程序。这个特殊的.svelte
扩展名以及我在教程中看到的非 Web 标准语法告诉我,我需要在编辑器中添加一些额外的支持来处理 Svelte。Svelte 博客上有一篇关于如何设置编辑器以与 Svelte 配合使用的精彩文章。我通常使用 Vim 或 VSCode,所以让我们将这两个编辑器都设置为与 Svelte 配合使用。
设置 VSCode 以与 Svelte 配合使用
对于 VSCode,有svelte-code插件提供.svelte
语法高亮、诊断、自动完成等功能的支持。
设置 Vim 以与 Svelte 配合使用
对于 Vim,设置编辑器文章并没有提供太多支持。它基本上会告诉你将.svelte
文件的文件类型更改为 HTML。经过一番挖掘,我发现了一些插件,它们可以让你在 Vim 中使用 Svelte 的体验更好,并达到 VSCode 的标准:
- vim-svelte为
.svelte
文件提供语法高亮和缩进 - coc-svelte通过连接到 Svelte LSP 2,为 Svelte 开发提供类似 IDE 的高级支持。它是coc.nvim自动补全插件(恰好是我最喜欢的 vim 补全插件)的扩展。
好的,现在我们已经设置好了编辑器,让我们仔细看看我们的新 Svelte 项目。
地形
我们打开il-pomodoro
编辑器内的文件夹,看到一堆文件和文件夹:
src
包含 Svelte hello world 应用程序源代码的文件夹- 一个
public
文件夹,其中包含我们的 Web 应用程序经过 Svelte 编译器编译和处理后的内容 rollup.config.js
包含我们的打包工具 ( rollup ) 的配置。Rollup 负责使用 Svelte 处理我们的源代码文件,以生成可在浏览器中运行的 dev 和 prod 打包文件。
对于初学者来说,最有趣的部分是src
文件夹内部,所以我们接下来就从那里开始。这个文件夹只包含两个文件:
App.svelte
这是我们应用程序的根组件main.js
其中包含初始化应用程序的引导代码
作为我们的应用程序入口点的文件是main.js
:
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
name: 'world'
}
});
export default app;
这将创建一个新的 SvelteApp
组件并将其附加到document.body
一个名为的 prop,title
其值为world
。
让我们看看App
具体是什么:
<script>
export let name;
</script>
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
<style>
main {
text-align: center;
padding: 1em;
max-width: 240px;
margin: 0 auto;
}
h1 {
color: #ff3e00;
text-transform: uppercase;
font-size: 4em;
font-weight: 100;
}
@media (min-width: 640px) {
main {
max-width: none;
}
}
</style>
我明白了!所以,Svelte 组件是一个可复用的 UI,它封装了组件的标记(HTML)、行为(<script>
标签内的 JavaScript)以及外观(<style>
标签内的 CSS)。太棒了!这很有道理。
如果我们深入研究标记,我们就能理解当我们指向浏览器时我们会看到什么localhost:5000
:
<main>
<h1>Hello {name}!</h1>
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
</main>
该 propname
在实例化时传递给组件,并保存在该name
变量中:
<script>
export let name;
</script>
然后,它会传播到组件的标记,并h1
在我们在浏览器中看到的标签内呈现。酷!这种略显奇怪却又熟悉的export let name
语法,正是Svelte 组件将其 API 定义为 props 的方式。
添加标题
让我们开始做一些简单的事情,比如为应用的第一个视图添加一个标题,并将其绑定到一些数据。初始模板给了我一些提示。我只需要在组件中添加一个新变量来包含该标题。由于name
原始模板中不需要该变量,所以我直接替换它:
<script>
export let title
</script>
并更新main.js
以注入我的应用程序的标题:
import App from './App.svelte';
const app = new App({
target: document.body,
props: {
title: 'il Pomodoro'
}
});
export default app;
再想想,我其实没必要把这个变量暴露成 prop。我们不希望组件的用户修改这个标题,所以就把它保留在组件内部吧。
让我们重写我们的 App 组件来执行此操作:
<script>
let title = "il Pomodoro";
</script>
最后,我将更新 HTML 模板以使用title
而不是name
:
<main>
<h1>{title}</h1>
</main>
搞定了!
任务列表
太棒了!我们继续创建一个非常简单的任务列表。因为这看起来是一个完全独立的功能,所以我们打算把它放在一个单独的组件中。
我创建了一个新文件TaskList.svelte
来表示该新组件,并添加了一些标记,以便在我使用它时尽可能少地出错App.svelte
:
<p>I'm a list of tasks</p>
我将其添加到App.svelte
:
<script>
let title = "il Pomodoro";
</script>
<main>
<h1>{title}</h1>
<TaskList />
</main>
<style>
/* styles omitted for sake of clarity. They'd be here. */
</style>
而且……它不起作用。嗯……我做错了什么……
VSCode 和浏览器都警告我以下情况:
'TaskList' is not defined. svelte(missing-declaration)
这告诉我两件事:
- 我的 vim 设置没有按预期工作,因为我没有在编辑器中收到错误(稍后会进行故障排除),并且
- 我好像忘记导入组件了!
当然!所以我把它添加到App.svelte
组件中:
<script>
let title = "il Pomodoro";
import TaskList from './TaskList.svelte';
</script>
<main>
<h1>{title}</h1>
<TaskList />
</main>
而且...是的!
现在我们来添加一些任务。我今天的三大任务是:
<script>
const tasks = [
"plan some fun trip with Teo",
"buy some flowers to my wife",
"write an article about Svelte"
];
</script>
现在我需要将它们以列表的形式显示在屏幕上。Svelte 有一种特殊的方法可以在模板中迭代列表:{#each} 块。
它的工作原理如下:
<ul>
{#each tasks as task}
<li>{task}</li>
{/each}
</ul>
因此,我们遍历task
列表中的每个元素tasks
,并将其放入列表项li
元素中。我们还从列表中删除了那些点,因为它们看起来很糟糕:
<style>
ul {
list-style: none;
}
</style>
这就是我们得到的:
叮叮叮!番茄工作法结束了。得走了!我们很快会继续推出更多 Svelte 功能、互动任务列表和番茄钟。
正在寻找番茄工作法应用程序的源代码?
别再找了!你可以在GitHub上找到它,可以直接克隆和使用,或者在Svelte REPL上找到它,你可以立即对其进行修改。
迄今为止的一些思考
太棒了!这真是快速上手 Svelte 的好方法。以下是我目前的感受:
- svelte.dev真的很棒。
- 交互式教程有一步一步的介绍,带您了解 Svelte 的所有功能和重要概念。
- Svelte 游乐场真的很酷,它可以让您使用 Svelte 创建多文件应用程序、保存它们并与您的朋友和同事分享。
- 开发文档也很棒,内容全面,而且有很多示例。收藏一下,需要的时候可以参考。
- 以上所有内容都为您提供了与 Svelte 的精彩初次接触,当您第一次进入一个新的生态系统时,您会非常感激。
- 创建新项目的方式有点奇怪。我习惯了所有流行的框架都有命令行界面,所以
npx degit etc...
创建新项目时有点困惑。不过,在最初的5秒困惑之后,我就直接运行了命令,继续我的生活。 - 我对文本编辑器支持的第一印象并不好,例如,VSCode 没有提供 Svelte 模板中的语句补全功能,而我原本期望它能用(例如,允许我过滤
tasks
)。在我短暂试用 Svelte 的这段时间里,Vim 的设置也没能正常工作。 - 使用 Svelte 本身是一种非常好的体验。
- 初次接触它,感觉它非常符合 Web 标准,一切运行都符合你的预期。“最小意外原则”在 Svelte 上得到了很好的体现。
<script>
我很喜欢 Svelte 组件的扁平结构,以及它用 HTML 标记、Javascript ( ) 和 CSS ( )划分组件的方式,<style>
非常合理。样板代码几乎可以忽略不计。- 在标记中注入数据很简单
- 尽管使用非标准方法暴露道具
export
很有意义并且很容易理解。 - 我想知道为什么 Svelte
{#each tasks as task}
可以使用{#for task of tasks}
并减少学习 Svelte 的人的认知负担。(也就是说,需要学习更多的自定义语法)
今天就到这里!希望你喜欢这篇文章。保重,期待更多 Svelte 内容的到来。
你是 Svelte 的资深用户吗?如果是的话,请随时指出我的做法有多么错误 :D 我很乐意听取你的意见,这样我们都能从中受益。
在 Vim 中修复 Svelte
经过一些故障排除后,我意识到按照 Svelte 博客中的建议,我之前已经使用自动命令设置了 Svelte,以将.svelte
文件的文件类型更新为html
:
augroup svelte
au! BufNewFile,BufRead *.svelte set ft=html
augroup END
这意味着 coc-vim 和 svelte 语法文件无法应用,因为它们期望的文件类型为svelte
。删除自动命令后,一切运行起来就像在 Visual Studio Code 中一样好。哇喔!
-
看看这个超级古老的番茄工作法应用程序,它是我在开始从事 Web 开发时使用 Knockout.js 编写的 。↩
-
LSP 代表语言服务器协议 (Language Server Protocol)。(摘自维基百科)它是一个基于 JSON-RPC 的开放协议,用于文本编辑器或 IDE 与提供特定编程语言功能的服务器之间。该协议的目标是允许独立于任何编辑器或 IDE 实现和分发编程语言支持 。↩