Svelte
Markets
Features
- No Virtual DOM
- Compiler/No base library
- Pure HTML/CSS/JS
Position
Runtime
Compiler
React
Svelte
Vue
Angular
Typescript
Babel ESNext
Pure JS
WebAssembly
Static analysis
AST/JIT
First look
// index.svelte
<script>
import NextStepKeyVisual from './_components/NextStepKeyVisual.svelte';
import EmploymentGoldCard from './_components/EmploymentGoldCard.svelte';
import Workspace from './_components/Workspace.svelte';
import Housing from './_components/Housing.svelte';
import EntrepreneurVisa from './_components/EntrepreneurVisa.svelte';
</script>
<style lang="scss">
.wrapper {
width: 100%;
max-width: 1280px;
margin: 0 auto;
padding: 80px 0 0 0;
}
</style>
<div class="wrapper">
<NextStepKeyVisual />
<EmploymentGoldCard />
<Workspace />
<Housing />
<EntrepreneurVisa />
</div>
SPA Routing
routify uses folder structure to define the router path
Template Condition
{#if porridge.temperature > 100}
<p>too hot!</p>
{:else if 80 > porridge.temperature}
<p>too cold!</p>
{:else}
<p>just right!</p>
{/if}
<h1>Shopping list</h1>
<ul>
{#each items as item}
<li>{item.name} x {item.qty}</li>
{/each}
</ul>
{#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}
<button disabled="{number !== 42}">...</button>
<button disabled={!clickable}>...</button>
Event Handler/Binding
<script>
let count = 0;
function handleClick(event) {
count += 1;
}
</script>
<button on:click={handleClick}>
count: {count}
</button>
<div
bind:offsetWidth={width}
bind:offsetHeight={height}>
<Chart {width} {height} />
</div>
<script>
import { onMount } from 'svelte';
let canvasElement;
onMount(() => {
const ctx = canvasElement.getContext('2d');
drawStuff(ctx);
});
</script>
<canvas bind:this={canvasElement}></canvas>
<script>
export let bar;
function foo(node, bar) {
// the node has been mounted in the DOM
return {
update(bar) {
// the value of `bar` has changed
},
destroy() {
// the node has been removed from the DOM
}
};
}
</script>
<div use:foo={bar}></div>
Animation/Transition
transition = (node: HTMLElement, params: any) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
css?: (t: number, u: number) => string,
tick?: (t: number, u: number) => void
}
animation = (node: HTMLElement, { from: DOMRect, to: DOMRect } , params: any) => {
delay?: number,
duration?: number,
easing?: (t: number) => number,
css?: (t: number, u: number) => string,
tick?: (t: number, u: number) => void
}
<div in:fly out:fade>
flies in, fades out
</div>
{#each list as item, index (item)}
<li animate:flip="{{ delay: 500 }}">{item}</li>
{/each}
Lifecycle
onMount(callback: () => void)
beforeUpdate(callback: () => void)
afterUpdate(callback: () => void)
onDestroy(callback: () => void)
promise: Promise = tick()
setContext(key: any, context: any)
context: any = getContext(key: any)
hasContext: boolean = hasContext(key: any)
dispatch: ((name: string, detail?: any) => void) = createEventDispatcher();
Store
import { writable } from 'svelte/store';
const count = writable(0, () => {
console.log('got a subscriber');
return () => console.log('no more subscribers');
});
count.set(1); // does nothing
const unsubscribe = count.subscribe(value => {
console.log(value);
}); // logs 'got a subscriber', then '1'
unsubscribe(); // logs 'no more subscribers'
import { readable } from 'svelte/store';
const time = readable(null, set => {
set(new Date());
const interval = setInterval(() => {
set(new Date());
}, 1000);
return () => clearInterval(interval);
});
store = writable(value?: any, start?: (set: (value: any) => void) => () => void)
store = readable(value?: any, start?: (set: (value: any) => void) => () => void)
store = derived(a, callback: (a: any) => any)
store = derived([a, ...b], callback: ([a: any, ...b: any[]]) => any)
derived likes React's useMemo
So, the cons?
No Virtual DOM
- You can not use dynamic JSX with variables easily. The template is static like Angular template, structure can not change largely like React.
- Testing only support E2E Test.
- Template driven's performance based on its static analyzer.
- Still has lifecycle, shouldComponentUpdate...
No base library
- Only has an advantage on a small project. When the project is larger, the base library bundle used low-percentage part in the bundle file.
- SPA routing, data layer still need library. You only can remove react-dom/render and react virtual dom diff.
tsài-huē
Svelte
By Chia Yu Pai
Svelte
- 451