38

Svelte 3 快速开发指南(对比React与vue)[每日前端夜话0x83]

 4 years ago
source link: https://www.tuicool.com/articles/EZzU32n
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

每日前端夜话 0x83

每日前端夜话,陪你聊前端。

每天晚上18:00准时推送。

正文共:5686 字

预计阅读时间: 13 分钟

翻译:疯狂的技术宅

来源: valentinog

QRjEVzn.jpg!web

Svelte 3 Tutorial For The Impatient Developer (2019)

什么是Svelte?

Svelte 是由 Rich Harris 创建的 JavaScript UI 库。 Rich 认为 virtual DOM 带来了额外开销,并提出了 Svelte,现在它正处于第三版的状态。

但是你为什么要学习Svelte?而不是 React 或 Vue?嗯,它有一些有趣的卖点:

  • Svelte是 编译器 ,而不是像 React 或 Vue 这样的依赖项

  • Svelte 似乎需要 更少的代码 ,用 React 开发同样的功能代码量大约会多 40% (来源:Rich Harris)

  • Svelte 没有 virtual DOM ,它会被编译成最小的 “vanilla” JavaScript,并且看起来比其他库性能更好

在下面的教程中,我更关注 Svelte 3 的核心概念。

不管怎样,不要过分的去追逐潮流。 Svelte 3 确实很有趣 ,虽然它在一些 细节上还比较粗糙 。你可以通过本教程来 试试 Svelte 3 的水到底有多深,并形成你自己的观点

请慢慢享用。

vARZ3iq.jpg!web

本指南适用于哪些人(要求)

如果你对以下内容有基本的了解,那么学习本教程就没有问题:

  • HTML、CSS 和 JavaScript (ES6+)

  • import 和 export 语法(ES6模块)

  • async/await 语法

  • 组件等概念

  • fetch API

如果你是前端初学者,那么这个教程对你来说也许太过分了。但是不要绝望,先学习以下资源然后再回来。

如果你需要学习 ES6模块 ,请查看 JavaScript 中关于 import 和 export 语句的文档。还有优秀的文章 ES6 Modules in depth【 https://ponyfoo.com/articles/es6-modules-in-depth 】。

要了解有关 Fetch API 的更多信息,请查看 Fetch API。

(是的,对于初学者来说,要学的东西是很多。但不是我的错!)。

最后还要确保在系统上安装了较新版本的 Node.js.

你将学习到的内容

我们不会在本教程中构建一个 “全栈的” 程序。相反,我将通过构建一些小的 UI 来引导你完成 Svelte 3 的核心概念 。最后,你应该能够开始使用 Svelte 进行构建,并了解了如何创建组件以及如何处理事件等等。

现在享受学习 Svelte 的乐趣!

设置项目

与所有现代 JavaScript 项目一样,我们需要完成设置项目所有必需的流程。如果要为项目创建 Git 仓库,请先完成这一步,然后在本地计算机上克隆仓库。

克隆后,你应该已准备好使用 degit 创建一个新的 Svelte 项目了。不用担心,这不是另一个需要学习的工具! Degit 是“愚蠢的”。它只是用来制作 Git repos 的副本,在我们的例子中,我们将把 Svelte 模板克隆到一个新文件夹中(或者在你的Git repo中)。

回顾一下,如果需要,可以创建一个新的Git仓库,然后在本地机器上克隆它:

1git clone [email protected]:yourusername/svelte-tutorial.git

然后用 degit 在新文件夹中创建一个新的 Svelte 项目。如果文件夹不是空的,degit 会报错,所以你需要加上强制标志:

1npx degit sveltejs/template svelte-tutorial --force

接下来进入新项目并安装依赖项:

1cd svelte-tutorial && npm i

现在你应该很高兴的上路了!

了解 Svelte 项目

项目就绪后,先来看看里面都有些什么。使用文本编辑器打开项目。你会看到一堆文件:

  • App.svelte:程序的根组件

  • rollup.config.js:Rollup 的配置,即 Svelte 选择的模块捆绑器

现在打开App.svelte并查看:

1<script>
2    export let name;
3</script>
4<style>
5    h1 {
6        color: purple;
7    }
8</style>
9<h1>Hello {name}!</h1>

这是一个 Svelte 组件 !真的,它需要的只是一个脚本标签、一个样式标签和一些 HTML。 name 是一个变量,然后在 HTML 中的 花括号 之间插入并使用。现在不要过分关注 export 声明,稍后会看到它的作用。

用 Svelte 获取数据

为了开始探索 Svelte,我们将立即开始用重火力进攻:先从 API 中获取一些数据。

就此而言,Svelte 与 React 没有什么不同:它使用名为 onMount 的方法。这是一个所谓的 生命周期函数 。很容易猜到 Svelte 从哪里借用了这个想法: React 生命周期方法

现在让我们在 src 文件夹中创建一个名为 Fetch.svelte 的新 Svelte 组件。我们的组件从 Svelte 导入 onMount 并向 API 发出获取请求。 onMount 接受回调,并从该回调中发出请求。数据保存在 onMount 内名为 data 的变量中:

1<script>
2  import { onMount } from "svelte";
3  let data = [];
4  onMount(async function() {
5    const response = await fetch("https://academy.valentinog.com/api/link/");
6    const json = await response.json();
7    data = json;
8  });
9</script>

现在打开 App.svelte 并导入新创建的组件(除了 script 标记,你可以删除所有内容):

1<script>
2  import Fetch from "./Fetch.svelte";
3</script>
4<Fetch />

正如你所看到的,自定义组件的语法让人想起 React 的 JSX。因为目前组件只是进行 API 调用,还不会显示任何内容。接下来让我们添加更多东西。

用“each”创建列表

在 React 中,我们已经习惯了创建元素列表的映射功能。在 Svelte 中有一个名为“ each ”的块,我们要用它来创建一个链接列表。 API 返回一个对象数组,每个对象都有一个标题和一个 url。现在要添加一个“each”块:

 1<script>
 2  import { onMount } from "svelte";
 3  let data = [];
 4  onMount(async function() {
 5    const response = await fetch("https://academy.valentinog.com/api/link/");
 6    const json = await response.json();
 7    data = json;
 8  });
 9</script>
10{#each data as link}
11// do stuff //
12{/each}

注意“each”是如何生成变量 data 的,我将每个元素提取为 “link”。要生成元素列表,只需确保将每个元素包装在一个 ul 元素中:

 1<script>
 2  import { onMount } from "svelte";
 3  let data = [];
 4  onMount(async function() {
 5    const response = await fetch("https://academy.valentinog.com/api/link/");
 6    const json = await response.json();
 7    data = json;
 8  });
 9</script>
10<ul>
11  {#each data as link}
12    <li>
13      <a href={link.url}>{link.title}</a>
14    </li>
15  {/each}
16</ul>

现在转到你的终端,进入项目文件夹并运行:

1npm run dev

访问 http://localhost:5000/ ,你应该看到一个链接列表:

jM7fm27.jpg!web

生成元素列表

很好!你学会了如何在 Svelte 中生成元素列表。接下来让我们的 组件可以重复使用

传递 props

重用UI组件的能力是这些现代 JavaScript 库的“存在理由”。例如在 React 中有 props 、自定义属性(甚至函数或其他组件),我们可以把它们传递给自己的组件,使它们更灵活。

现在 Fetch.svelte 不是可重用的,因为 url 是硬编码的。但不必担心, Svelte 组件也可以从外面接收props 。让首先将 url 变为一个变量(我将向你展示组件的相关部分):

 1<script>
 2  import { onMount } from "svelte";
 3  let url = "https://academy.valentinog.com/api/link/";
 4  let data = [];
 5  onMount(async function() {
 6    const response = await fetch(url);
 7    const json = await response.json();
 8    data = json;
 9  });
10</script>

有一个技巧可以使 url 成为 props:只需在变量前加上 export

 1<script>
 2  import { onMount } from "svelte";
 3  // export the variable to make a prop
 4  export let url = "https://academy.valentinog.com/api/link/";
 5  let data = [];
 6  onMount(async function() {
 7    const response = await fetch(url);
 8    const json = await response.json();
 9    data = json;
10  });
11</script>

现在打开 App.svelte 并通过传递 url prop 来更新 Fetch 组件:

1<script>
2  import Fetch from "./Fetch.svelte";
3</script>
4<Fetch url="https://jsonplaceholder.typicode.com/todos" />

现在,你的组件调用的是新端点而不是默认 URL。另一个好处是标记为 props 的 变量可能具有默认值 。在我们的例子中,“https://academy.valentinog.com/api/link/”是 默认 props ,作为没有 props 传递时的后备。

现在看看当我们需要不止一个 props 时会发生什么。

多 props 及传播

当然,Svelte 组件可能有多个 props。让我们为组件添加另一个名为 title 的 props:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  export let title = "A list of links";
 5  let data = [];
 6  onMount(async function() {
 7    const response = await fetch(url);
 8    const json = await response.json();
 9    data = json;
10  });
11</script>
12<h1>{title}</h1>
13<ul>
14  {#each data as link}
15    <li>
16      <a href={link.url}>{link.title}</a>
17    </li>
18  {/each}
19</ul>

再次从 App.svelte 传递新的 props:

1<script>
2  import Fetch from "./Fetch.svelte";
3</script>
4<Fetch
5  url="https://jsonplaceholder.typicode.com/todos"
6  title="A list of todos" />

当 props 开始增多时,你会发现上述方法不切实际。幸运的是,有一种方法可以 传播 props 。将 props 声明为对象并将它们分布在组件上:

1<script>
2  import Fetch from "./Fetch.svelte";
3  const props = {
4    url: "https://jsonplaceholder.typicode.com/todos",
5    title: "A list of todos"
6  };
7</script>
8<Fetch {...props} />

很不错不是吗?但我仍然不满意。我想让 Fetch 组件更加可重用 ,该怎么办?

子组件和“渲染” props

Fetch 这个命名对于组件来说并不差劲,如果它是一个 HTML 列表的话。有一种方法可以从外面传递该列表, 就像React 中的子 props 一样。在 Svelte,我们将子组件称为 插槽(slot)

第一步,我将从 Fetch.svelte 中删除所有标记,将其替换为 插槽 ,使它摆脱 prop 的“title”:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  let data = [];
 5  onMount(async function() {
 6    const response = await fetch(url);
 7    const json = await response.json();
 8    data = json;
 9  });
10</script>
11<slot />

接下来,可以将子元素从外部传递给 Fetch,这就发生在 App.svelte 中:

 1<script>
 2  import Fetch from "./Fetch.svelte";
 3  const props = {
 4    url: "https://jsonplaceholder.typicode.com/todos"
 5  };
 6</script>
 7<Fetch {...props}>
 8  <h1>A list of todos</h1>
 9  <ul>
10    <li>now what?</li>
11  </ul>
12</Fetch>

但现在我们遇到了问题。我需要 data ,它存在于 Fetch.svelte 中,这点很重要,因为我不想手动去创建列表。

在 React 中你可以找到一个 HOC、 渲染 props 或 hooks。换句话说,我想渲染一个子组件,但是子组件应该从父组件获取 data

在 Svelte 中,你可以通过将值 反向 传递给父组件来获得相同的结果。首先将 data 作为 prop 传递给你的插槽:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  export let title = "A list of links";
 5  let data = [];
 6  onMount(async function() {
 7    const response = await fetch(url);
 8    const json = await response.json();
 9    data = json;
10  });
11</script>
12<!-- {data} is a shortand for data={data} -->
13<slot {data} />

从外面你可以使用符号 let:data={data} 访问 数据 ,这里简写为 let:data

 1<script>
 2  import Fetch from "./Fetch.svelte";
 3  const props = {
 4    url: "https://jsonplaceholder.typicode.com/todos"
 5  };
 6</script>
 7<!-- let:data is like forwarding a component's data one level upward -->
 8<Fetch {...props} let:data>
 9  <h1>A list of todos</h1>
10  <ul>
11    {#each data as link}
12      <li>{link.title}</li>
13    {/each}
14  </ul>
15</Fetch>

现在可以使用来自 Fetch 组件的 数据 了,它可用于我的每个块。这就像 将组件的内部数据向上转发一级

虽然起初可能是反直觉的,但这似乎是一种简洁的方法。你怎么看?在下一节中,我们将介绍 Svelte 中的事件处理。

处理事件和事件修饰符

我们将构建一个表单组件来说明 Svelte 如何处理事件。创建一个名为 Form.svelte 的新文件。现在它包含用于搜索的 input 和提交类型的 button

1<script>
2</script>
3<form>
4  <label for="search">Search:</label>
5  <input type="search" id="search" required />
6  <button type="submit">Search</button>
7</form>

(作为练习,你可以将每个元素提取到其自己的组件中)。

然后在 App.svelte 中包含新组件:

1<script>
2  import Form from "./Form.svelte";
3</script>
4<Form />

现用程序应该可以在浏览器中渲染你的表单了。此时如果你尝试提交表单, 默认行为 是:浏览器触发刷新。

要控制 “vanilla” 中的表单,我会为 submit 事件注册一个事件监听器。然后在处理 handler 内部阻止使用 event.preventDefault() 的默认值:

1// vanilla JS example
2var form = document.getElementsByTagName('form')[0]
3form.addEventListener('submit', function(event){
4    event.preventDefault();
5});

在 Svelte 组件内部情况有所不同: 使用“on”注册事件handler ,后面分别使用事件名称和处理函数:

 1<script>
 2  function handleSubmit(event) {
 3    // do stuff
 4  }
 5</script>
 6<form on:submit={handleSubmit}>
 7  <label for="search">Search:</label>
 8  <input type="search" id="search" required />
 9  <button type="submit">Search</button>
10</form>

此外在 Svelte 中有 事件修饰符 。其中最重要的是:

  • preventDefault

  • stopPropagation

  • once

可以在事件名称之后使用修饰符 preventDefault停用表单上的默认

 1<script>
 2  function handleSubmit(event) {
 3    // do stuff
 4  }
 5</script>
 6<form on:submit|preventDefault={handleSubmit}>
 7  <label for="search">Search:</label>
 8  <input type="search" id="search" required />
 9  <button type="submit">Search</button>
10</form>

还可以将 handleSubmit 作为 prop 来传递,以便使组件更加灵活。这是一个例子:

 1<script>
 2  export let handleSubmit = function(event) {
 3    // default prop
 4  };
 5</script>
 6<form on:submit|preventDefault={handleSubmit}>
 7  <label for="search">Search:</label>
 8  <input type="search" id="search" required />
 9  <button type="submit">Search</button>
10</form>

而已。现在把这个简单的程序更进一步: 我想过滤链接列表 。表单已经到位但我们需要将 Fetch.svelteForm.svelte 连接起来。我们开始做吧!

快速回顾

让我们回顾一下到目前为止所做的事情。我们有两个组件, Fetch.svelte

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  let data = [];
 5  onMount(async function() {
 6    const response = await fetch(url);
 7    const json = await response.json();
 8    data = json;
 9  });
10</script>
11<slot {data} />

和 Form.svelte:

 1<script>
 2  export let handleSubmit = function(event) {
 3    // default prop
 4  };
 5</script>
 6<form on:submit|preventDefault={handleSubmit}>
 7  <label for="search">Search:</label>
 8  <input type="search" id="search" required />
 9  <button type="submit">Search</button>
10</form>

App.svelte是根组件。为方便起见,让我们在 App 中渲染 Form 和 Fetch:

 1<script>
 2  import Fetch from "./Fetch.svelte";
 3  import Form from "./Form.svelte";
 4</script>
 5<Form />
 6<Fetch let:data>
 7  <h1>A list of links</h1>
 8  <ul>
 9    {#each data as link}
10      <li>
11        <a href={link.url}>{link.title}</a>
12      </li>
13    {/each}
14  </ul>
15</Fetch>

Fetch.svelte从 API 获取数据并向上转发 数据 。因此当使用 块作为插槽 时,可以将 数据 传递给它的子节点。

现在我希望用户根据他在表单中输入的搜索词来过滤 数据 。看起来像 Form 和 Fetch 需要沟通 。让我们看看如何实现这一点。

实现搜索功能

我们需要一个搜索项来过滤 数据 数组。搜索词可以是从外部传递给 Fetch.svelte 的 props。打开 Fetch.svelte 并添加新的 prop searchTerm:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  // new prop
 5  export let searchTerm = undefined;
 6  let data = [];
 7  onMount(async function() {
 8    const response = await fetch(url);
 9    const json = await response.json();
10    data = json;
11  });
12</script>
13<slot {data} />

(searchTerm 被指定为 undefined,以防止 Svelte 对我抱怨 “Fetch 在创建时找不到预期的 prop searchTerm”)。

接下来需要一个新变量来保存 json 响应,因为我们将根据 searchTerm 过滤该响应。添加一个名为 jsonResponse 的新变量,使用 jsonResponse 来存储 API 的响应而不是将 json 保存到数据:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  // new prop
 5  export let searchTerm;
 6  // new variable
 7  let jsonResponse = [];
 8  let data = [];
 9  onMount(async function() {
10    const response = await fetch(url);
11    const json = await response.json();
12    // save the response in the new variable
13    jsonResponse = json;
14  });
15</script>
16<slot {data} />

此时变量 数据 将包含:

  • 如果没有提供 searchTerm,则为原始 jsonResponse

  • 如果 searchTerm 不为空,则为过滤后的数组

对于过滤数组元素,我们可以基于 RegExp 对照标题属性进行匹配。 (API返回一个对象数组。每个对象都有 title 和 url)。第一个实现可能是:

1 const regex = new RegExp(searchTerm, "gi");
2  const data = searchTerm
3    ? jsonResponse.filter(element => element.title.match(regex))
4    : jsonResponse;

说得通!让我们看看完整的组件:

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  // new prop
 5  export let searchTerm = undefined;
 6  // new variable
 7  let jsonResponse = [];
 8  const regex = new RegExp(searchTerm, "gi");
 9  const data = searchTerm
10    ? jsonResponse.filter(element => element.title.match(regex))
11    : jsonResponse;
12  onMount(async function() {
13    const response = await fetch(url);
14    const json = await response.json();
15    // save the response in the new variable
16    jsonResponse = json;
17  });
18</script>
19<slot {data} />

在这一点上,我们需要对 App.svelte 进行一些调整。 searchTerm 应该是来自外部的动态 props。然后我们在用户提交表单时拦截输入的值。打开 App.svelte 并将 searchTerm 作为 Fetch 的 prop 传递:

 1<script>
 2  import Fetch from "./Fetch.svelte";
 3  import Form from "./Form.svelte";
 4  let searchTerm;
 5</script>
 6<Form />
 7<Fetch {searchTerm} let:data>
 8  <h1>A list of links</h1>
 9  <ul>
10    {#each data as link}
11      <li>
12        <a href={link.url}>{link.title}</a>
13      </li>
14    {/each}
15  </ul>
16</Fetch>

接下来我们创建并传递 handleSubmit 作为 Form 的 prop,并在 App.svelte 内部保存用户在变量 searchTerm 中输入的搜索词:

 1<script>
 2  import Fetch from "./Fetch.svelte";
 3  import Form from "./Form.svelte";
 4  let searchTerm;
 5  function handleSubmit() {
 6    const { value } = this.elements.search;
 7    searchTerm = value;
 8  }
 9</script>
10<Form {handleSubmit} />
11<Fetch {searchTerm} let:data>
12  <h1>A list of links</h1>
13  <ul>
14    {#each data as link}
15      <li>
16        <a href={link.url}>{link.title}</a>
17      </li>
18    {/each}
19  </ul>
20</Fetch>

几乎完成了。保存所有文件并运行开发服务器。你会看到……一个空白的页面!

yQnUnuj.png!web

Svelte 3 tutorial reactivity

这是怎么回事?赶快进入下一节!

反应式编程

Svelte 处理 计算值 的方式可能一开始看起来不直观。我们的问题在于 Fetch.svelte ,它来自以下几行:

1 const regex = new RegExp(searchTerm, "gi");
2  const data = searchTerm
3    ? jsonResponse.filter(element => element.title.match(regex))
4    : jsonResponse;

思考一下,假设我们有两个值, regex 取决于 searchTerm ,我们希望每次后者更改时要重新生成前者。

然后我们有 数据 :它应该每次重新处理 searchTerm正则表达式 。就像电子表格一样 :一个值可能取决于其他值

Svelte 从“反应式编程”中汲取灵感,并对所谓的计算值使用奇怪的语法。这些值在 Svelte 3 中被称为“ 反应声明 ”。下面是应该如何调整上述代码:

1 $: regex = new RegExp(searchTerm, "gi");
2  $: data = searchTerm
3    ? jsonResponse.filter(element => element.title.match(regex))
4    : jsonResponse;

$:不是外来的语法。它只是简单的 JavaScript,它被称为标签声明。

这里是完整的 Fetch.svelte

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "https://academy.valentinog.com/api/link/";
 4  export let searchTerm = undefined;
 5  let jsonResponse = [];
 6  $: regex = new RegExp(searchTerm, "gi");
 7  $: data = searchTerm
 8    ? jsonResponse.filter(element => element.title.match(regex))
 9    : jsonResponse;
10  onMount(async function() {
11    const response = await fetch(url);
12    const json = await response.json();
13    jsonResponse = json;
14  });
15</script>
16<slot {data} />

现在,搜索功能将像魔法一样工作:

buUZzqj.jpg!web

反应式表单

(过滤 API 级别的链接比每次获取所有链接更好)。

如果你想知道如何用 React实现相同的“app” ,请看下一部分。

与 React 的对比

用 React 构建的相同功能的 demo 看起来是怎样的呢?这是 App.js ,相当于 App.svelte

 1import React, { useState } from "react";
 2import Fetch from "./Fetch";
 3import Form from "./Form";
 4function App() {
 5  const [searchTerm, setSearchTerm] = useState("");
 6  const fetchProps = {
 7    url: "https://academy.valentinog.com/api/link/",
 8    searchTerm
 9  };
10  function handleSubmit(event) {
11    event.preventDefault();
12    const { value } = event.target.elements.search;
13    setSearchTerm(value);
14  }
15  return (
16    <>
17      <Form handleSubmit={handleSubmit} />
18      <Fetch
19        {...fetchProps}
20        render={links => {
21          return (
22            <>
23              <h1>A list of links</h1>
24              <ul>
25                {links.map(link => (
26                  <li key={link.url}>
27                    <a href={link.url}>{link.title}</a>
28                  </li>
29                ))}
30              </ul>
31            </>
32          );
33        }}
34      />
35    </>
36  );
37}
38export default App;

这里我使用带有渲染 props 的 Fetch 组件。我可以使用 hook,但我想告诉你同样的概念如何适用于 Svelte 和React。

换一种说法:

  • 对于 从React 中的子组件访问父组件的状态 ,你可以使用 render props (或用于共享数据获取的自定义hook)

  • 对于 从 Svelte 插槽 访问父组件的状态,你可以 从父节点向上转发

如果你将 App.js 与 Svelte 对应代码(点击这里)【 https://github.com/valentinogagliardi/svelte-tutorial/blob/master/src/App.svelte 】进行比较,可以看到典型的 Svelte 组件比 React 等效组件更加简洁

通过在 Svelte 3 中 的事实很容易解释,不需要显式调用 setSomeState 或类似的函数。 仅通过为变量赋值,Svelte 就能“做出反应”

接下来是 Form.jsForm.svelte 的 React 实现:

 1import React from "react";
 2function Form(props) {
 3  return (
 4    <form onSubmit={props.handleSubmit}>
 5      <label htmlFor="search">Search:</label>
 6      <input type="search" id="search" required={true} />
 7      <button type="submit">Search</button>
 8    </form>
 9  );
10}
11export default Form;
12

没有什么可看的,只是一个函数接受一些 props。

最后是 Fetch.js ,复制 Fetch.svelte 的功能:

 1import { useState, useEffect } from "react";
 2function Fetch(props) {
 3  const { url, searchTerm } = props;
 4  const [links, setLinks] = useState([]);
 5  const regex = new RegExp(searchTerm, "gi");
 6  const data = searchTerm
 7    ? links.filter(link => link.title.match(regex))
 8    : links;
 9  useEffect(() => {
10    fetch(url)
11      .then(response => response.json())
12      .then(json => setLinks(json));
13  }, [url]);
14  return props.render(data);
15}
16Fetch.defaultProps = {
17  url: "https://academy.valentinog.com/api/link/"
18};
19export default Fetch;

上面的组件使用 hook 和渲染 props:再次强调这是不必要的,因为你可以提取 自定义 hook 。这里是 Fetch.svelte

 1<script>
 2  import { onMount } from "svelte";
 3  export let url = "fillThis";
 4  export let searchTerm = undefined;
 5  let jsonResponse = [];
 6  $: regex = new RegExp(searchTerm, "gi");
 7  $: data = searchTerm
 8    ? jsonResponse.filter(element => element.title.match(regex))
 9    : jsonResponse;
10  onMount(async function() {
11    const response = await fetch(url);
12    const json = await response.json();
13    jsonResponse = json;
14  });
15</script>
16<slot {data} />

他们看起来和我一样帅:grinning:。然而,这些 例子远远达不到一个真正的大程序的地步

Svelte 与 React 和 Vue 相比是怎样的?

我被问到 与 React 和 Vue 相比 ,对 Svelte 的看法是什么?我不能评价 Vue,因为我没有太多的使用经验,但我可以看到 Svelte 如何向其借鉴的。

说到 React,Svelte 对我来说很合理,看起来 更直观。在粗略的一瞥中,Svelte 3 似乎只是另一种做事方式,也许比 React 更聪明。

在 Svelte 中真正吸引人的是,它与 React 和 Vue 不同, 没有 virtual DOM 。换句话说,库和实际的文档对象模型之间没有抽象:Svelte 3 可被编译为可能的最小原生 JavaScript。如果你在受限制的环境中运行程序,这将非常有用。

回顾一下,Svelte 是一个非常有趣的库,但至少在文档、生态系统和工具将逐渐成熟之前我会给它更多的时间。

资源

为了解更多关于 Svelte 的信息,我不能只推荐官方文档【 https://svelte.dev/docs 】和例子【 https://svelte.dev/examples 】。

本教程的源代码在这里【 https://github.com/valentinogagliardi/svelte-tutorial 】。

另外请务必去看一看 Svelte 作者的演讲:https://www.youtube.com/embed/AdNJ3fydeao

总结

还能做些什么?如果你愿意,Svelte 3 还有很多要学的东西。开箱即用的好东西太多了:

  • scoped styles

  • 双向绑定

  • 状态管理

  • 内置动画

说再见之前,我还要再啰嗦几句。

JavaScript是残酷的。各种库来去匆匆,总会有新的东西需要学习。多年来,我学会了不要过于依赖任何特定的 JavaScript 库,但说实话,我真的很喜欢 React 和 Redux。

React 为大家带来了“组件”,另一方面,库本身需要具有高度专业化的知识才能掌握。相比之下,Vue 更适合初学者,但不幸的是它并不像 React 那样被视为“时尚”(无论那意味着什么)。

Svelte 3 充分利用了两个世界:Svelte 组件看起来像 Vue,而 React 的一些概念也同样适用。

Svelte 比 React更直观,特别是当一个初学者在 hook 时代去接触 React 时。当然,React 不会很快消失,但我很期待看到 Svelte 的未来。

最后我仍然要老生常谈: 要持续不断的学习

原文:https://www.valentinog.com/blog/svelte/

图书推荐

下面夹杂一些私货:也许你和高薪之间只差这一张图

2019年京程一灯课程体系上新,这是我们第一次将全部课程列表对外开放。

愿你有个好前程,愿你月薪30K。我们是认真的 ! BbquyaF.png!web

zMFVruu.jpg!web

在公众号内回复“体系”查看高清大图

长按二维码,加大鹏老师微信好友

拉你加入前端技术交流群

唠一唠怎样才能拿高薪

JFNJFbv.jpg!web

小手一抖,资料全有。长按二维码关注 前端先锋 ,阅读更多技术文章和业界动态。

MFryQjN.gif


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK