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

栏目: 服务器 · 发布时间: 5年前

内容简介:翻译:疯狂的技术宅来源:

每日前端夜话 0x83

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

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

正文共:5686 字

预计阅读时间: 13 分钟

翻译:疯狂的技术宅

来源: valentinog

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

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 的水到底有多深,并形成你自己的观点

请慢慢享用。

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

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

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

  • 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 git@github.com: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/ ,你应该看到一个链接列表:

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

生成元素列表

很好!你学会了如何在 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>

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

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

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} />

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

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

反应式表单

(过滤 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。我们是认真的 ! Svelte 3 快速开发指南(对比React与vue)[每日前端夜话0x83]

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

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

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

拉你加入前端技术交流群

唠一唠怎样才能拿高薪

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

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

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


以上所述就是小编给大家介绍的《Svelte 3 快速开发指南(对比React与vue)[每日前端夜话0x83]》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

疯狂Java讲义

疯狂Java讲义

李刚 / 电子工业出版社 / 2012-1-1 / 109.00元

《疯狂Java讲义(附光盘第2版)》是《疯狂Java讲义》的第2版,第2版保持了第1版系统、全面、讲解浅显、细致的特性,全面介绍了新增的Java 7的新特性。 《疯狂Java讲义(附光盘第2版)》深入介绍了Java编程的相关方面,全书内容覆盖了Java的基本语法结构、Java的面向对象特征、Java集合框架体系、Java泛型、异常处理、Java GUI编程、JDBC数据库编程、Java注释、......一起来看看 《疯狂Java讲义》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

URL 编码/解码
URL 编码/解码

URL 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具