乐趣区

关于前端:Svelte-带来哪些新思想赶紧学起来

本文介绍

点赞 + 关注 + 珍藏 = 学会了

Svelte 是我用过最爽的框架,就算 Vue 和 React 再弱小,生态再好,我还是更喜爱 Svelte,因为它开发起来真的很爽。

其实在很久之前我就留神到 Svelte,但始终没把这个框架放在心上。

因为我之前的工作次要应用 Vue,偶然也会接触到一些 React 我的项目,但齐全没遇到过应用 Svelte 的我的项目。

直到 Vite 的呈现,我才开始开始器重 Svelte。

从 Vite 文档 里能够看到它反对这些模板:

JavaScript TypeScript
vanilla vanilla-ts
vue vue-ts
react react-ts
preact preact-ts
lit lit-ts
svelte svelte-ts

能让祖师爷也器重的框架,不简略不简略~

我喜爱用 Demo 的形式学习新技术,Svelte 官网入门教程 就提供了这种形式。

这是我感觉入门比拟难受且不便日后搜寻的学习形式。

尽管 Svelte 官网入门教程 曾经给出很多例子,而且 Svelte 中文网 也有对应的翻译,但有些翻译看上去是机译,而且局部案例可能不太适宜老手学习~

本文的目标是把 Svelte 的学习流程梳理进去,让第一次接触 Svelte 的工友能顺利上手。

本文适宜人群:有 HTMLCSSJS 根底,晓得并曾经装置了 Node

如果你是打算从 0 开始学习前端,那本文临时还不适宜你浏览。

Svelte 简介

Svelte 是一个构建 web 应用程序的工具。

传统框架如 React 和 Vue 在浏览器中须要做大量的工作,而 Svelte 将这些工作放到构建应用程序的编译阶段来解决。

须要留神,Svelte 是一款编译器。它能够将依照规定语法编写的代码打包成浏览器能运行的我的项目。

和其余前端框架一样,同样也是应用 HTMLCSSJavaScript 进行开发。

作者

在学习 Svelte 之前先理解一下它的父亲(作者)。

Svelte 的作者叫 Rich Harris,正在吃货色的这位就是他。

可能国内大多数工友对他不是很相熟(我也齐全不熟),但应该听过 Rollup。

没错,他也是 Rollup 的爸爸。

他在开发 Svelte 之前还开发过 Ractive.js,据说 Vue 的局部实现也是受到了 Ractive 的启发。

对于 Rich Harris 的介绍还有很多,我搜到的材料上这样介绍到:

  • 大学业余是学哲学的
  • 在纽约时报调查组工作的图形编辑,身兼记者和开发者职位

还有更多对于他和 Svelte 的介绍,能够看看《Svelte – The magical disappearing UI framework – Interview with Rich Harris》

Svelte 的劣势

Svelte 翻译成中文就是“苗条”的意思,侧面表明它打包进去的包十分小。

Svelte 次要劣势有以下几点。

1. 编译器

在关上 Svelte 官网时就能看到这样的介绍。

Svelte 是一种全新的构建用户界面的办法。传统框架如 React 和 Vue 在浏览器中须要做大量的工作,而 Svelte 将这些工作放到构建应用程序的编译阶段来解决。

Svelte 组件须要在 .svelte 后缀的文件中编写,Svelte 会将编写好的代码翻编译 JSCSS 代码。

2. 打包体积更小

Svelte 在打包会将援用到的代码打包起来,而没援用过的代码将会被过滤掉,打包时不会退出进来。

在《A RealWorld Comparison of Front-End Frameworks with Benchmarks (2019 update)》报告中,对支流框架进行了比照。

在通过 gzip 压缩后生成的包大小,从报告中能够看出,Svelte 打包进去的体积甩开 Vue、React 和 Angular 几条街。

这是因为通过 Svelte 编译的代码,仅保留援用到的局部。

3. 不应用 Virtual DOM

Virtual DOM 就是 虚构 DOM,是用 JS 对象形容 DOM 节点的数据,由 React 团队推广进去的。

虚构 DOM 是前端的网红,因而也有很多开发者开始钻研和搞辩论赛。

网上有一张图比照了 Svelte 和 React 在数据驱动视图的流程

其实次要比照了应用虚构 DOM 和间接操作实在 DOM 的区别。

在 React 中实现数据驱动视图大略流程是这样的:

数据发生变化 -> 通过 diff 算法判断要更新哪些节点 -> 找到要更新的节点 -> 更新实在 DOM

Vue 的数据更新原理其实也差不多,只是实现形式和应用语法会有所不同。

diff 算法 会依据数据更新前和更新后生成的虚构 DOM 进行比照,只有两个版本的虚构 DOM 存在差别时,才会更新对应的实在 DOM。

应用虚构 DOM 比照的形式会比间接比照实在 DOM 的效率高。

而且实在 DOM 身上挂载的属性和办法十分多,应用虚构 DOM 的形式去形容 DOM 节点树会显得更轻便。

但这也意味着每次数据发生变化时都要先创立一个虚构 DOM,并应用 diff 算法 将新虚构 DOM 与旧虚构 DOM 进行比对,这个步骤会耗费一点性能和须要一点执行工夫。

而 Svelte 在未应用虚构 DOM 的状况下实现了响应式设计。

我以粗犷的形式了解:Svelte 会监听顶层组件所有变量,一旦某个变量发生变化,就更新应用过该变量的组件。这就仅仅只需更新受影响的那局部 DOM 元素,而不须要整个组件更新。

综上所述,在我的理解力,虚构 DOM 的思维很优良,也是顺应时代的产物,但虚构 DOM 并不是最快的,JS 间接操作 DOM 才是最快。

《Virtual DOM is pure overhead》是 Svelte 官网上的一篇博客,专门探讨虚构 DOM。有趣味的工友能够看看~

4. 更天然的响应式

这也是我刚接触 Svelte 时立即喜爱上的理由。

这里说的响应式设计是只对于数据的响应,而不是像 Bootstrap 的响应式布局。

当初风行的前端框架根本都应用 数据驱动视图 这个概念,像 Vue 和 React 这些框架,都有响应式数据的概念。

但 Vue 和 React 在数据响应方面还是有点“不那么天然”,我简略举几个例子:

  • 在 React 中,如果须要更新数据并在视图中响应,须要应用 setState 办法更新数据。
  • 在 Vue2 中,响应式数据要放在 data 里,在 methods 中应用 this.xxx 来更新数据。
  • 在 Vue3 的 Composition API 语法中,须要应用 ref 或者 reactive 等办法包裹数据,应用 xxx.value 等形式批改数据。

下面这几种状况,感觉多少都增加了点货色能力实现响应式数据性能(至多在一般开发者开发时是这样)。

在 Svelte 的理念中,响应式应该给开发者一种无感体验,比方在 Excel 中,当我规定 C1 单元格的值是 A1 + B1 的和,设置好规定后,用户只须要批改 A1 和 B1 即可,C1 会主动响应,而不需再做其余操作。

在这方面,Svelte 我认为在现阶段是做得最天然的。

<h1>{name}</h1>

<script>
  let name = '雷猴'

  setTimeout(() => {name = '鲨鱼辣椒'}, 1000)
</script>

下面的代码中,1 秒后批改 name 的值,并更新视图。

从代码就能看出,在应用 Svelte 开发我的项目时,开发者个别无需应用额定的办法就能做到和 Vue、React 的响应式成果。

如果你对 Svelte 响应式原理感兴趣,举荐浏览 FESKY 的《Svelte 响应式原理分析 —— 从新思考 Reactivity》

也能够看看《Rethinking reactivity》,看看官网对 reactivity 的思考。

5. 性能强

Stefan Krause 给出一份 性能测试报告(点击可查看)比照里多个热门框架的性能。从 Svelte 的性能测试后果能够看出,Svelte 是相当优良的。

6. 内存优化

性能测试报告(点击可查看)也列出不同框架的内存占用水平,Svelte 对内存的治理做到十分极致,占用的内存也是十分小,这对于配置不高的设施来说是件坏事。

第 5 和 6 点,因为测试报告比拟长,我没截图放进文中。大家有趣味能够点开链接查看测试报告。

7. 更关注无障碍体验

在应用 Svelte 开发时会 主动对无障碍拜访方面的体验进行检测,比方 img 元素没有增加 alt 属性,Svelte 会向你收回一条正告。无障碍体验对非凡人事来说是很有帮忙的,比方当你在 img 标签中设置好 alt 属性值,应用有声浏览器会把 alt 的内容读出来。

在此我还要举荐 2 本对于设计体验的书。

  • 《点石成金:访客至上的 Web 和挪动可用性设计秘笈》
  • 《包容性 Web 设计》

它们的封面长别离这个样子

Svelte 的劣势必定还有很多,但因为我开发经验不足,只能总结出以上这些了。如果你对 Svelte 有更多了解,欢送在评论区补充~

Svelte 的有余

  1. Svelte 对 IE 是十分不敌对的,但我并不把这放在眼里。如果想兼容 IE 我还是举荐应用 jQuery。
  2. Svelte 的生态不够丰盛。因为是“新宠”,生态方面必定是不如 Vue 和 React 的。

与 Svelte 相干的库

Sapper

Sapper 官网地址

Sapper 是构建在 Svelte 上的框架,Sapper 提供了页面路由、布局模板、SSR 等性能。

Svelte Native

Svelte Native 官网地址

Svelte Native 是建设在 NativeScript 之上的产物,能够开发安卓和 iOS 利用,是一个跨端技术。

有点相似于 React Native 和 Weex 之类的货色。

svelte-gl

svelte-gl 仓库

svelte-gl 还没正式公布,但这是个很乏味的工具,它和 three.js 相似,专门做 3D 利用的。

尽管当初 github 上的 Star 还不是很多,但也能够写些 demo 玩玩。

创立我的项目

在开始之前,你须要在电脑上装置 Node 环境。

编辑工具我应用了 VS Code,同时装置了 Svelte for VS Code 扩大插件。

应用 Svelte 前,必须有一个开发环境。

创立或应用开发环境有以下几种形式:

  1. REPL
  2. Rollup
  3. Webpack
  4. Parcel
  5. Vite

本文应用的是 Vite 创立我的项目,但下面列出的所有形式我都会逐个说说。

REPL

REPL 是 Svelte 提供的一个线上环境,关上 Svelte 官网 能够看到顶部导航栏下面有个 REPL 的选项。点击该选项就能够跳转到 Svelte 线上开发环境了。

REPLread(读取)evaluate(执行)print(打印)loop(循环) 这几个单词的缩写。

如果你只是想尝试 Svelte 的某些性能或者测试小型代码,能够应用这款线上工具。

REPL 还提供了多组件开发,按左上角的 + 号 能够创立新组件。组件的内容稍后会说到。

界面右侧,顶部有 3 个选项:

  • Result: 运行后果。
  • JS output: Svelte 编译后的 JS 代码。
  • CSS output: Svelte 编译后的 CSS 代码。

REPL 界面右上角还有一个下载按钮。

当你在线上环境写好代码,能够点击下载按钮把我的项目保留到本地,下载的文件是一个 zip,须要本人手动解压。

而后应用以下命令初始化我的项目并运行即可。

# 1、初始化我的项目
npm install

# 2、运行我的项目
npm run dev

# 3、在浏览器拜访 http://localhost:5000

运行后果:

Rollup 版

Svelte 官网也提供了一个命令,能够下载 Svelte 我的项目到本地。

命令最初须要输出你的项目名称。

# 1、下载模板
npx degit sveltejs/template 项目名称

# 2、装置依赖
npm install

# 3、运行我的项目
npm run dev

# 4、在浏览器拜访 http://localhost:8080

运行后果:

这是官网提供的创立我的项目形式,这个我的项目是应用 Rollup 打包的。

Rollup 和 Svelte 都是同一个作者(Rich Harris)开发的,用回自家货色很失常。

Webpack 版

如果你不想应用 Rollup 打包我的项目,能够尝试应用 Webpack。

# 1、下载模板
npx degit sveltejs/template-webpack 项目名称

# 2、装置依赖
npm install

# 3、运行我的项目
npm run dev

# 4、在浏览器拜访 http://localhost:8080/

运行后果:

Parcel 版

我并 不举荐应用 该办法创立我的项目,因为 Svelte 并没有提供应用 Parcel 打包工具的模板。但 GitHub 上有第三方的解决方案(点击拜访仓库)。

将 DeMoorJasper/parcel-plugin-svelte 的代码下载下来。

# 1、进入 `packages/svelte-3-example` 目录

# 2、装置依赖
npm install

# 3、运行我的项目
npm run start

# 4、在浏览器拜访 http://localhost:1234/

运行后果:

Vite 版

本文接下来所有例子都是应用 Vite 创立 Svelte 我的项目进行开发的。

应用 Vite 创立我的项目的起因是:快!

# 1、下载模板的命令
npm init vite@latest

# 2、输出我的项目名

# 3、抉择 Svelte 模板(我没选 ts)# 4、进入我的项目并装置依赖
npm install

# 5、运行我的项目
npm run dev

# 6、在浏览器拜访 http://127.0.0.1:5173/

运行后果:

本文应用 Vite 创立我的项目,目录构造和 Rollup 版 创立进去的我的项目构造略微有点不同,但开发逻辑是一样的。

起步

index.htmlsrc/main.jssrc/App.svelte 这三个是最次要的文件。

index.html 是我的项目运行的入口文件,它外面援用了 src/main.js 文件。

src/main.js 里引入了 src/App.svelte 组件,并应用以下代码将 src/App.svelte 的内容渲染到 #app 元素里。

const app = new App({target: document.getElementById('app')
})

target 指明指标元素。

咱们大部分代码都是写在 .svelte 后缀的文件里。

.svelte 文件次要保安 多个 HTML 元素 1 个 script 元素 1 个 style 元素。这 3 类元素都是可选的。

咱们次要的工作目录是 src 目录。

为了加重学习难度,咱们先做这几步操作。

1、清空全局款式

如果你应用 Rollup 版 创立我的项目,不须要做这一步。

在应用 Vite 创立的 Svelte 我的项目中,找到 src/app.css 文件,并把外面的内容清空掉。

2、革新 src/App.svelte

src/App.svelte 文件改成以下内容

<script>
  let name = '雷猴'

  function handleClick() {name = '鲨鱼辣椒'}
</script>

<div>Hello {name}</div>
<button on:click={handleClick}> 改名 </button>

此时点击按钮,页面上的“雷猴”就会变成“鲨鱼辣椒”

下面的代码其实和 Vue 有点像。

  • 变量和办法都写在 <script> 标签里。
  • HTML 中应用 {} 能够绑定变量和办法。
  • 通过 on:click 能够绑定点击事件。

只需写以上代码,Svelte 就会主动帮咱们做数据响应的操作。一旦数据产生扭转,视图也会主动扭转。

是不是非常简单!

根底模板语法

Svelte 的模板语法其实和 Vue 是有点像的。如果你之前曾经应用过 Vue,那本节学起来就非常简单。

插值

在“起步章节”曾经应用过 插值 了。在 Svelte 中,应用 {} 大括号将 script 里的数据绑定到 HTML 中。

<script>
  let name = '雷猴'
</script>

<div>{name}</div>

此时页面上就会呈现 name 的值。

这种语法和 Vue 是有点像的,Vue 应用双大括号的形式 {{}} 绑定数据。Svelte 就少一对括号。

表达式

HTML 中除了能够绑定变量外,还能够绑定表达式。

<script>
  let name = '雷猴'

  function sayHi() {return `${name} 世界!`
  }

  let a = 1
  let b = 2

  let state = false
</script>

<div>{sayHi()}</div>

<div>{a} + {b} = {a + b}</div>

<div>{state ? '雷猴' : '鲨鱼辣椒'}</div>

属性绑定

HTML 的属性须要动静绑定数据时,也是应用 {} 语法。

<script>
  let name = '雷猴'
</script>

<div title={name}>Hello</div>

当鼠标放到 div 标签上时,会呈现 title 里的提示信息。

渲染 HTML 标签 @html

如果只是应用插值的办法渲染带有 HTML 标签的内容,Svelte 会主动本义 <> 之类的标签。

<script>
  let h1El = '<h1 style="color: pink;"> 雷猴 </h1>'
</script>

<div>{h1El}</div>

这种状况少数呈现在渲染富文本。

在 Vue 中有 v-html 办法,它能够将 HTML 标签渲染进去。在 Svelte 中也有这个办法,在插值后面应用 @html 标记一下即可。

<script>
  let h1El = '<h1 style="color: pink;"> 雷猴 </h1>'
</script>

<div>{@html h1El}</div>

但此办法有可能蒙受 XSS 攻打。

我在《NodeJS 避免 xss 攻打》中简略演示过 XSS 攻打,有趣味的能够看看。

款式绑定

在日常开发中,给 HTML 标签设置款式次要通过 行内 styleclass 属性。

根底的 HTML 写法和原生的一样,这里不过多解说。

上面次要讲动静设置款式,也就是将 JS 里的变量或者表达式绑定到 style 或者 class 里。

行内款式 style

<script>
  let color = 'red'

  setTimeout(() => {color = 'blue'}, 1000)
</script>

<div style="color: {color}"> 雷猴 </div>

1 秒后,文字从红色变成蓝色。

绑定 class

<script>
  let foo = true

  setTimeout(() => {foo = false}, 1000)
</script>

<div class:active={foo}> 雷猴 </div>

<style>
  .active {color: red;}
</style>

HTML 里能够应用 class:xxx 动静设置要激活的类。这里的 xxx 是对应的类名。

语法是 class:xxx={state},当 statetrue 时,这个款式就会被激活应用。

条件渲染 #if

应用 {#if} 结尾,{/if} 结尾。

根底条件判断

{#if 条件判断}
...
{/if}

举个例子

<script>
  let state = true

  setTimeout(() => {state = false}, 1000)
</script>

{#if state}
  <div> 雷猴 </div>
{/if}

1 秒后扭转状态

两种条件

{#if 条件判断}
...
{:else}
...
{/if}

举个例子

<script>
  let state = true

  setTimeout(() => {state = false}, 1000)
</script>

{#if state}
  <div> 雷猴 </div>
{:else}
  <div> 鲨鱼辣椒 </div>
{/if}

多种条件

{#if 条件判断}
...
{:else if 条件判断}
...
{/if}

举个例子

<script>
  let count = 1

  setInterval(() => {count++}, 1000)
</script>

{#if count === 1}
  <div> 雷猴 </div>
{:else if count === 2}
  <div> 鲨鱼辣椒 </div>
{:else}
  <div> 蟑螂恶霸 </div>
{/if}

条件渲染的用法比较简单,只有 JS 根底就能看得懂。

列表渲染 #each

如果你有一堆数据须要展现进去,能够应用 #each 办法。

应用 {#each} 结尾,{/each} 结尾。

遍历数组

{#each expression as name}
...
{/each}

举个例子

<script>
  let list = ['a', 'b', 'c', 'd', 'e', 'f']
</script>

<ul>
  {#each list as item}
      <li>{item}</li>
  {/each}
</ul>

要留神,Svelte 和 Vue 的遍历在写法上有点不同。

Vue 的形式是:

<div v-for="元素 in 源数据">
  <span>{{元素}}</span>
</div>

Svelte 的形式是:

<div>
  {#each 源数据 as 元素}
    <span>{元素}</span>
  {/each}
</div>

遍历数组(带下标)

<script>
  let list = ['a', 'b', 'c', 'd', 'e', 'f']
</script>

<ul>
  {#each list as item, index}
      <li>{index} -- {item}</li>
  {/each}
</ul>

留神:as 前面首先跟着元素,而后才是下标。而且元素和下标不须要用括号括起来。

如果元素是对象,能够解构

<script>
  let list = [{name: '雷猴'},
    {name: '鲨鱼辣椒'}
  ]
</script>

<ul>
  {#each list as {name}}
      <li>{name}</li>
  {/each}
</ul>

默认内容

如果源数据没有内容,是空数组的状况下,还能够组合 {:else} 一起应用。

<script>
  let list = []
</script>

<div>
  {#each list as {name}}
      <div>{name}</div>
  {:else}
      <div> 暂无数据 </div>
  {/each}
</div>

事件绑定 on:event

应用 on: 指令监听 DOM 事件,on: 前面追随事件类型

语法:

on: 事件类型 ={事件名}

举个例子,点击按钮时在控制台输入“雷猴”。

<script>
  function sayHi() {console.log('雷猴')
  }
</script>

<button on:click={sayHi}> 打招呼 </button>

绑定其余事件(比方 change 等)也是同样的情理。

事件修饰符

如果你只心愿某些事件只执行一次,或者勾销默认行为,或者阻止冒泡等,能够应用事件修饰符。

语法:

on: 事件类型 | 修饰符 ={事件名}

举个例子,我心愿点击事件只能执行一次,之后再点击都有效,能够应用官网提供的 once 修饰符。

<script>
  function sayHi() {console.log('雷猴')
  }
</script>

<button on:click|once={sayHi}> 打招呼 </button>

从上图能够看出,屡次点击都只是输入 1 次“雷猴”。

除了 once 之外,还有以下这些修饰符能够用:

  • preventDefault:禁止默认事件。在程序运行之前调用 event.preventDefault()
  • stopPropagation:调用 event.stopPropagation(), 避免事件达到下一个标签
  • passive:改善了 touch/wheel 事件的滚动体现(Svelte 会在适合的中央主动加上它)
  • capture:示意在 capture阶段而不是 bubbling 触发其程序
  • once:程序运行一次后删除本身

串联修饰符

修饰符还能够串联起来应用,比方 on:click|once|capture={...}

但须要留神,有些非凡的标签应用修饰符会呈现“意想不到”的后果,比方 <a> 标签。

<script>
  function toLearn() {console.log('还在思考要不要学 Canvas')
  }
</script>

<a
  href="https://juejin.cn/post/7116784455561248775"
  on:click|once|preventDefault={toLearn}
> 去学习 Canvas?</a>

原本是想给 <a> 标签绑定一个点击事件,第一次点击时在控制台输入一句话,并且禁止 <a> 标签的默认事件。

所以应用了 oncepreventDefault 修饰符。

但实际上并非如此。下面的代码意思是 once 设定了只执行一次 toLearn 事件,并且只有一次 preventDefault 是无效的。

只有点击时就不触发 toLearn 了,而且 preventDefault 也会生效。所以再次点击时,<a> 元素就会触发本身的跳转性能。

数据绑定 bind

数据绑定通常会和表单元素联合应用。

bind 能够做到双向数据绑定的成果。我感觉 Svelte 里的 bind 有点像 Vue 的 v-model

语法:

bind:property={variable}

input 单行输入框

<script>
  let msg = 'hello'

  function print() {console.log(msg)
  }
</script>

<input type="text" value={msg} />
<button on:click={print}> 打印 </button>

如果只是应用 value={msg} 的写法,input 默认值是 hello,当输入框的值产生扭转时,并没有把内容反馈回 msg 变量里。

此时就须要应用 bind 了。

<!-- 省略局部代码 -->
<input type="text" bind:value={msg} />

textarea 多行文本框

多行文本框同样绑定在 value 属性上。

<script>
  let msg = 'hello'
</script>

<textarea type="text" bind:value={msg} />
<p>{msg}</p>

input range 范畴抉择

因为都是 input 元素,只是 type 不同而已。所以范畴抉择元素同样须要绑定 value

<script>
  let val = 3
</script>

<input type="range" bind:value={val} min=0 max=10 />
<p>{val}</p>

radio 单选

单选框通常是成组呈现的,所以要绑定一个非凡的值 bind:grout={variable}

<script>
  let selected = '2'
</script>

<input type="radio" bind:group={selected} value="1" />
<input type="radio" bind:group={selected} value="2" />
<input type="radio" bind:group={selected} value="3" />
<p>{selected}</p>

checkbox 复选框

<script>
  let roles = []
</script>

<input type="checkbox" bind:group={roles} value="雷猴" />
<input type="checkbox" bind:group={roles} value="鲨鱼辣椒" />
<input type="checkbox" bind:group={roles} value="蟑螂恶霸" />
<input type="checkbox" bind:group={roles} value="蝎子莱莱" />

<p>{roles}</p>

select 选择器

<script>
  let selected = 'a'
</script>

<select bind:value={selected}>
    <option value='a'>a</option>
    <option value='b'>b</option>
    <option value='c'>c</option>
</select>

<span>{selected}</span>

select multiple 选择器

multiplecheckbox 有点像。

<script>
  let selected = []
</script>

<select multiple bind:value={selected}>
    <option value="雷猴"> 雷猴 </option>
    <option value="鲨鱼辣椒"> 鲨鱼辣椒 </option>
    <option value="蟑螂恶霸"> 蟑螂恶霸 </option>
    <option value="蝎子莱莱"> 蝎子莱莱 </option>
</select>

<span>{selected}</span>

简写模式

如果 bind 绑定的属性和在 JS 里申明的变量名雷同,那能够间接绑定

<script>
  let value = 'hello'
</script>

<input type="text" bind:value />

<p>{value}</p>

这个例子中,bind:value 绑定的属性是 value,而在 JS 中申明的变量名也叫 value,此时就能够应用简写的形式。

$: 申明反馈性

通过应用$: JS label 语法作为前缀。能够让任何位于 top-level 的语句(即不在块或函数外部)具备反馈性。每当它们依赖的值产生更改时,它们都会在 component 更新之前立刻运行。

下面这段解释是官网文档的解释。

$: 在文档中称为 Reactivity,中文文档成它为 反馈性能力

但我应用 $: 时,感觉这个性能有点像 Vue 的 computed

$: 能够监听表达式外部的变动从而做出响应。

<script>
  let count = 0;
  $: doubled = count * 2;

  function handleClick() {count += 1;}
</script>

<button on:click={handleClick}>
  点击加 1
</button>

<p>{count} 翻倍后 {doubled}</p>

应用 $: 申明的 double 会主动依据 count 的值扭转而扭转。

如果将以上代码中 $: 改成 let 或者 var 申明 count,那么 count 将失去响应性。

这样看来,真的和 Vue 的 computed 的作用有那么一点像。

异步渲染 #await

Svelte 提供异步渲染标签,能够晋升用户体验。

语法:

{#await expression}
...
{:then name}
...
{:catch name}
...
{/await}

#await 开始,以 /await 完结。

:then 代表胜利后果,:catch 代表失败后果。

expression 是判断体,要求返回一个 Promise

其实用法和 #if ... :else if ... /if 有那么一丢丢像。

举个例子

<script>
  const api = new Promise((resolve, reject) => {setTimeout(() => {resolve('申请胜利,数据是 xxxxx')
    }, 1000)
  })
</script>

{#await api}
  <span>Loading...</span>
{:then response}
  <span>{response}</span>
{:catch error}
  <span>{error}</span>
{/await}

如果将下面的 resolve 改成 reject 就会走 :catch 分支。

根底组件

在 Svelte 中,创立组件只须要创立一个 .svelte 为后缀的文件即可。

通过 import 引入子组件。

比方,在 src 目录下有 App.sveltePhone.svelte 两个组件。

App.svelte 是父级,想要引入 Phone.svelte 并在 HTML 中应用。

App.svelte

<script>
  import Phone from './Phone.svelte'
</script>

<div> 子组件 Phone 的内容:</div>
<Phone />

Phone.svelte

<div> 电话:13266668888</div>

组件通信

组件通信次要是 父子组件 之间的数据来往。

父传子

比方下面的例子,手机号心愿从 App.svelte 组件往 Phone.svelte 里传。

能够在 Phone.svelte 中申明一个变量,并公开该变量。

App.svelte 就能够应用对应的属性把值传入。

App.svelte

<script>
  import Phone from './Phone.svelte'
</script>

<div> 子组件 Phone 的内容:</div>
<Phone number="88888888" />

Phone.svelte

<script>
  export let number = '13266668888'
</script>

<div> 电话:{number}</div>

如果此时 App.svelte 组件没有传值进来,Phone.svelte 就会应用默认值。

子传父

如果想在子组件中批改父组件的内容,须要把批改的办法定义在父组件中,并把该办法传给子组件调用。

同时须要在子组件中引入 createEventDispatcher 办法。

App.svelte

<script>
  import Phone from './Phone.svelte'
  function print(data) {console.log(` 手机号: ${data.detail}`)
  }
</script>

<div> 子组件 Phone 的内容:</div>
<Phone on:printPhone={print} />

Phone.svelte

<script>
  import {createEventDispatcher} from 'svelte'
  const dispatch = createEventDispatcher()

  function printPhone() {dispatch('printPhone', '13288888888')
  }
</script>

<button on:click={printPhone}> 输入手机号 </button>

父组件承受参数是一个对象,子组件传过来的值都会放在 detail 属性里。

插槽 slot

和 Vue 一样,Svelte 也有组件插槽。

在子组件中应用 <slot> 标签,能够接管父组件传进来的 HTML 内容。

App.svelte

<script>
  import Phone from './Phone.svelte'
</script>

<div> 子组件 Phone 的内容:</div>
<Phone>
  <div> 电话:</div>
  <div>13288889999</div>
</Phone>

Phone.svelte

<style>
    .box {
        width: 100px;
        border: 1px solid #aaa;
        border-radius: 8px;
        box-shadow: 2px 2px 8px rgba(0,0,0,0.1);
        padding: 1em;
        margin: 1em 0;
    }
</style>

<div class="box">
    <slot> 默认值 </slot>
</div>

生命周期

生命周期是指我的项目运行时,指定期间会主动执行的办法。

Svelte 中次要有以下几个生命周期:

  • onMount: 组件挂载时调用。
  • onDestroy: 组件销毁时执行。
  • beforeUpdate: 在数据更新前执行。
  • afterUpdate: 在数据更新实现后执行。
  • tick: DOM 元素更新实现后执行。

以上生命周期都是须要从 svelte 里引入的。

onMount 举个例子

<script>
  import {onMount} from 'svelte'
  let title = 'Hello world'
  
  onMount(() => {console.log('onMount')
    setTimeout(() => title = '雷猴', 1000)
  })
</script>

<h1>{title}</h1>

在组件加载完 1 秒后,扭转 title 的值。

onDestroybeforeUpdateafterUpdate 都和 onMount 的用法差不多,只是执行的工夫条件不同。你能够本人创立个我的项目试试看。

tick 是比拟非凡的,tick 和 Vue 的 nextTick 差不多。

在 Svelte 中,tick 的应用语法如下:

import {tick} from 'svelte'

await tick()
// 其余操作

总结

本文次要解说了 Svelte 的根底用法,但 Svelte 的内容和 API 远不止此。它还有很多高级的用法以及提供了过渡动画性能等,这些都会放在高级篇解说。

Svelte 是一个 Web 利用的构建工具,它打包进去的我的项目体积比拟小,性能强,不应用虚构 DOM。

Svelte 的兼容性和周边生态相比起 VueReact 会差一点。

所以日常我的项目中须要依据 Svelte 的优缺点进行取舍。

举荐浏览

举荐书籍

  • 《点石成金:访客至上的 Web 和挪动可用性设计秘笈》
  • 《包容性 Web 设计》

举荐文章

  • 👍《Canvas 从入门到劝敌人放弃(图解版)》
  • 👍《SVG 从入门到悔恨,怎么不早点学起来(图解版)》
  • 👍《Fabric.js 从入门到收缩》
  • 👍《Vue3 过 10 种组件通信形式》
  • 👍《CSS 也能用数字命名?》

点赞 + 关注 + 珍藏 = 学会了
代码仓库

退出移动版