---
title: "开箱Svelte"
description: "1. Svelte超甜的语法(类似Vue)。2.Svelte 内置的响应式store方案(类似RxJS，但是精简易学)3. 语法惊奇有趣（褒义，就像逍遥派派的功夫较之于少林的功夫）。4.Svelte小型业余项目推荐使用（编写速度和build代码大小是优势）。"
url: "https://hicc.pro/p/blog/intro-svelte"
author: "tyler wang"
published: "2019-12-28T06:17:02.000Z"
updated: "2021-07-03T09:06:30.000Z"
category: "blog"
tags:
  - "Svelte"
  - "Markdwon Editor"
  - "Markdown"
  - "Ghost"
  - "Ghost editor"
image: "https://image.hicc.pro/pro/20210703170529FrFJUN0QJpzkz1vNXI3yTRC_kX2vDlvy0c88Mf1myKImC4kLk.jpg"
lang: "zh-CN"
site: "Hipo日志"
---

# 开箱Svelte

2019年的最后一天了，前端仍然是React，Vue，Angular三大框架的天下，大概率到了明年此时仍然是它们的天下，不过各路神仙们仍然在孜孜不倦的创造着轮子😄，最有名的”轮子哥“自然是创造了rollup的[Rich-Harris](https://github.com/Rich-Harris)了，最近的项目是一个web框架[Svelte](https://github.com/sveltejs/svelte)。

> Svelte is a radical new approach to building user interfaces. Whereas traditional frameworks like React and Vue do the bulk of their work in the browser, Svelte shifts that work into a compile step that happens when you build your app.

Svelte不一样在于：
- 所谓“消失即逝”的框架，尽可能通过静态编译减少框架运行时的代码量，这点本文不展开，感兴趣的可以看Vue作者[尤大关于Svelte的知乎答案](https://www.zhihu.com/question/53150351/answer/133912199)。
- 不使用Virtual Dom
- 真响应式

抛开这些太过官网的说辞，吸引我的是：

- 作者一个超精彩的视频：[Rethinking Reactivity](https://youtu.be/AdNJ3fydeao)
- 超甜的语法(类似Vue)。
- 内置的响应式store方案(类似RxJS，但是精简易学)

……

经过一个比预期漫长，比预期曲折的chrome extension([Ghost-MDE](https://chrome.google.com/webstore/detail/ghost-mde/laoklpeeddabbhgamhegeimhgljfjedc?authuser=0) -- Writing ghost post with markdown editor)开发之后(项目已开源：[https://github.com/yijian166/ghost-mde](https://github.com/yijian166/ghost-mde)，我想写下这篇Svelte开箱，个人的简短观点是：

- 语法惊奇有趣（褒义，就像逍遥派派的功夫较之于少林的功夫）。
- 小型业余项目推荐使用（编写速度和build代码大小是优势）。
- 正式，公司级，中文圈不建议（资料不太多，有些概念有别于React这种“不成文的标准”）。

---

### Svelte基础

Svelte基本使用方式上和Vue很相似，组件的HTML，CSS，JS写在一个`.svelte`的文件中。

```html
<script>
	let count = 0;

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

<style>
	button {
	  background: #ff3e00;
	  color: white;
	  border: none;
	  padding: 8px 12px;
	  border-radius: 2px;
	}
</style>

<button on:click={handleClick}>
  Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
```

#### 模版语法

##### `if`

```html
{#if porridge.temperature > 100}
	<p>too hot!</p>
{:else if 80 > porridge.temperature}
	<p>too cold!</p>
{:else}
	<p>just right!</p>
{/if}
```

##### 循环语法`each`

```html
{#each items as item, i}
	<li>{i + 1}: {item.name} x {item.qty}</li>
{/each}
```

##### 异步加载`await`

甚至可以直接在模版中使用promise

```html
{#await promise}
	<!-- promise is pending -->
	<p>waiting for the promise to resolve...</p>
{:then value}
	<!-- promise was fulfilled -->
	<p>The value is {value}</p>
{:catch error}
	<!-- promise was rejected -->
	<p>Something went wrong: {error.message}</p>
{/await}
```

##### 元素指令

Svelte中的元素指令可以让你很方便的操控元素。

- 事件监听on:eventname： `on:eventname|modifiers={handler}`
- 属性绑定bind:property： `bind:property={variable}`
	- 甚至可以只读的绑定`clientWidth`,`clientHeight`,`offsetWidth`,`offsetWidth`
- 组合input(radio, checkbox)属性绑定bind:group={variable}
- 获取DOM节点或组件的实例，bind:this ：`bind:this={dom_node}`	
- class绑定，`div class="{active ? 'active' : ''}">...</div>`,`<div class:active class:inactive={!active} class:isAdmin>...</div>`
- 以及常用的`slot`
- ……

总体来说来svelte基础语法实在易用，上手也很容易。更多可以查看[Svelte API文档](https://svelte.dev/docs)。

#### 神奇的符号 `$`

Svelte巧妙的使用了一个js中没什么用的`$`符号，来表达响应。

```js
let a = 0;
$: b = a + 5;
```
变量b的值会随着a的变化而变化。甚至可以包裹成更复杂代码快。

```js
let a = 1;
let b = 2;
$: {
	if (a+b > 10){
		// do something
	}
}
```

#### Svelte 生命周期

web框架，特别是组件化的框架，自然会有生命周期，Svelte也不例外：

- onMound： `onMount(callback: () => () => void)`
- beforeUpdate: `beforeUpdate(callback: () => void)`
- afterUpdate: `afterUpdate(callback: () => void)`
- onDestroy: `onDestroy(callback: () => void)`

行为和大家熟知Vue，React的基本一样。

#### Svelte dispatch, Context

Svelte组件的组合，以及组件的通信和Vue的非常的类似， 属性自上而下通过`$$props`传递，子组件向上dispath事件。

```html
<script>
	import { createEventDispatcher } from 'svelte';

	const dispatch = createEventDispatcher();
</script>

<button on:click="{() => dispatch('notify', 'detail value')}">Fire Event</button>
```

这样自然也有跨组件通信的问题，Svelte则是提供了`context`， 不过和Svelte store 结合，使用也挺容易。

```js
import { writable } from "svelte/store";
const nameStore = writable("name");

setContext("name", nameStore);

function changeName() {
	nameStore.set("name2");
}
```

```html
<div>
	<p>{$name}</p>
</div>

<script>
import { getContext } from "svelte";
const name = getContext("name");
</script>
```

---

so far so good, 下面进入Svelte真正有趣的地方🤓

### Svelte store使用

现代的数据驱动框架，绕不开的就是状态管理库，Svelte则是提供了一个**相当精巧易用的方案**, [Svelte store](https://svelte.dev/docs#svelte_store)。

Svelte store的思路和响应式框架RxJS很像，但是在保留响应式能力的同时，尽可能降低了使用难度（不会像RxJS那么高的门槛， 甚至也不像redux那么死板），这点给Svelte点赞👍👍👍。

#### writable

可以使用writable来创建一个可写的store。

```js
store = writable(value: any, (set: (value: any) => void) => () => void)
```

使用也很简单

```html
<div>{$count}</div>
<script>
import { writable } from 'svelte/store';

const count = writable(0);

count.subscribe(value => {
	console.log(value);
}); // logs '0'

count.set(1); // logs '1'

count.update(n => n + 1); // logs '2'
</script>
```

- `subscribe`方法来订阅store的变化
- `set`方法设置值，`update`方法使用函数来方便拿到store中的值，再设置新的值。
- HTML模版中使用`$`来引用store。

#### readable

```js
store = readable(value: any, (set: (value: any) => void) => () => void)
```

使用readable来创建可以外部不可写的store。

```js
import { readable } from 'svelte/store';

const time = readable(new Date(), set => {
	const interval = setInterval(() => {
		set(new Date());
	}, 1000);

	return () => clearInterval(interval);
});
```

#### derived

[derived](https://svelte.dev/docs#derived)才是真正点燃store的地方，它接受store然后转换为一个新的store，这其实RxJS中诸多的Operator做的事情，没有那么强大，但也降低了使用门槛。

```js
store = derived(a, callback: (a: any) => any) // 可以接受单个store
store = derived([a, ...b], callback: ([a: any, ...b: any[]], set: (value: any) => void) => void | () => void, initial_value: any) // 也可以接受多个store
```

这里不会展开很多，个人认为**derived可能是svelte最闪光的地方了，利用好的这个功能，会为你的代码增色不少**。

### Svelte的一点点不爽

- **不支持Typescript**，2020年啦，这个算是个不小的缺陷。
- **Svelte stroe在值发生变化时才会“响应”**。这点和RxJS不一样。
- 有些不正常的写法可能不会触发响应，譬如，[通过函数参数传递响应变量，会导致不响应](https://codesandbox.io/s/confident-chebyshev-kuo70?fontsize=14&hidenavigation=1&theme=dark)……，这些初写可能会让你很沮丧😄
- ……

### 总结

总体来说Svelte提供了一种大三框架之外的思路和开发体验，值得大家学习，也鼓励大家在业余小型项目中使用。

---

原文 / Source: <https://hicc.pro/p/blog/intro-svelte>
