探索Svelte
什么是Svelte
Svelte本意是苗条纤瘦的,Svelte是一种构建用户界面的全新方法,它被预测为未来十年可能取代React和Vue等其他框架的新兴技术。作者是前端轮子哥 Rich Harris,同时也是 Rollup 的作者。
他设计 Svelte 的核心思想在于『通过静态编译减少框架运行时的代码量』,也就是说,vue 和 react 这类传统的框架,都必须引入运行时 (runtime) 代码,用于虚拟dom、diff 算法。Svelted完全溶入JavaScript,应用所有需要的运行时代码都包含在bundle.js里面了,除了引入这个组件本身,你不需要再额外引入一个运行代码。
从2019年开始, Svelte出现在榜单中。刚刚过去的2020年,Svelte在满意度排行榜中超越了react,跃升到了第一位。
Svelte的优势
从容量大小来看,Vue58k,React97.5k,而Svelte只有9.7k。性能方面略逊Vue但是强于React。代码量方面碾压Vue和React。同时,Svelte自带数据框架。
Svelte的劣势
- 没有像AntD那样成熟的UI库。
- Svelte 原生不支持预处理器,比如说less/scss。
- Svelte 原生脚手架没有目录划分。
- 暂时不支持typescript,虽然官方说了会支持, 但是不知道什么时候。
Svelte如何处理渲染问题
众所周知,React采用的虚拟DOM和diff算法来解决渲染问题,但是由于React 采用jsx语法本质不理解数据代表的意义,没有办法做出优化,因此才会出现诸如pureComponent,shouldComponentUpdate,useMemo,useCallback这些生命周期来控制重复渲染问题。
而Svelte 采用了Templates语法(类似于Vue 的写法),更加严格和具有语义性,可以在编译的过程中就进行优化操作。1
2
3
4
5
6
7<template>
    <div>
        <p>{{name}}</p>
        <p>8888</p>
        <p>8888</p>
    </div>
</template>
编译器针对这块template代码可以很清楚地知道哪些代码是会变动,哪些代码不会变动。
Svelte实例代码
- 小demo
App.svelte1
2
3
4
5
6
7<script>
	import Button from './button.svelte'
	let name = 'world';
</script>
<h1>Hello {name}!</h1>
<Button/>
button.svelte1
2
3
4
5
6
7
8
9
10<script>
    let count = 0;
    function handleClick() {
        count += 1;
    }
</script>
<button on:click={handleClick}>
	Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
- $:响应式语句
| 1 | let count = 0; | 
在 Svelte 中,以 $: 开头的语句就是响应式语句,Svelte 会自动分析响应式语句所依赖的变量,当依赖变量发生变化时,Svelte 就会重新执行相应的响应式语句。当 Svelte 看到任何带有 $: 前缀的语句时,它就知道要将右边的变量赋值给左边的变量,而不需要使用let将一个变量的值绑定到另一个变量;并且Svelte可以以响应式的方式运行任何语句。1
2
3
4
5
6
7
8
9$: console.log(`the count is ${count}`);
$: {
	console.log(`the count is ${count}`);
	alert(`I SAID THE COUNT IS ${count}`);
}
$: if (count >= 10) {
	alert(`count is dangerously high!`);
	count = 9;
}
但是Svelte的响应是基于赋值操作的,数组的 push、splice 等操作不会触发响应式更新。
- 接收Props
| 1 | <script> | 
- 生命周期 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12- <script> 
 import { onMount,onDestroy,beforeUpdate,afterUpdate,tick } from 'svelte';
 let photos = [];
 onMount(async () => {
 const res = await fetch(`https://jsonplaceholder.typicode.com/photos?_limit=20`);
 photos = await res.json();
 });
 
 onDestroy(() => alert('gg'));
 </script>
- 逻辑判断 
 由于HTML没有类似于逻辑判断的语法,因此- Svelte加了个这个东西。- 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37- <script> 
 let user = { loggedIn: false };
 function toggle() {
 user.loggedIn = !user.loggedIn;
 }
 </script>
 {#if user.loggedIn}
 <button on:click={toggle}>
 Log out
 </button>
 {/if}
 {#if !user.loggedIn}
 <button on:click={toggle}>
 Log in
 </button>
 {/if}
 //或
 {#if user.loggedIn}
 <button on:click={toggle}>
 Log out
 </button>
 {:else}
 <button on:click={toggle}>
 Log in
 </button>
 {/if}
 //或
 {#if x > 10}
 <p>{x} is greater than 10</p>
 {:else if 5 > x}
 <p>{x} is less than 5</p>
 {:else}
 <p>{x} is between 5 and 10</p>
 {/if}
- 遍历 - 1 
 2
 3
 4
 5- {#each cats as cat} 
 <li><a target="_blank" href="https://www.youtube.com/watch?v={cat.id}">
 {cat.name}
 </a></li>
 {/each}
- await - 1 
 2
 3
 4
 5
 6
 7- {#await promise} 
 <p>...waiting</p>
 {:then number}
 <p>The number is {number}</p>
 {:catch error}
 <p style="color: red">{error.message}</p>
 {/await}
- 事件绑定1 
 2
 3
 4
 5
 6<button on:click|once={handleClick}> 
 Click me
 </button>
 <button on:click={handleClick}>
 Click me
 </button>
自定义事件
| 1 | <script> | 
- Store1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38store.js 
 import { writable,readable,derived } from 'svelte/store';
 export const count = writable(0);//writable类型的store有update和set两种subscribe方法
 export const time = readable(new Date(), function start(set) {
 const interval = setInterval(() => {
 set(new Date());
 }, 1000);
 return function stop() {
 clearInterval(interval);
 };
 });
 //readable无法从外部进行更新,没有set()或update()方法。一旦设置了初始状态,便无法从外部进行修改。
 export const elapsed = derived(
 time,
 $time => Math.round(($time - 100*Math.random()) / 1000)
 );
 //derived允许您创建依赖于现有存储的值的新存储值
 app.svelte
 <script>
 import { count } from './stores.js';
 import Incrementer from './Incrementer.svelte';
 import Decrementer from './Decrementer.svelte';
 import Resetter from './Resetter.svelte';
 let count_value;
 const unsubscribe = count.subscribe(value => {
 count_value = value;
 });
 </script>
 <h1>The count is {count_value}</h1>
综上。
