SlideShare a Scribd company logo
Svelte
Chris Noring
@chris_noring
Cloud Advocate at Microsoft
WHY
• Less cruft/ boilerplate
• It’s fast, no Virtual DOM
• No script tag, Svelte bundles stand-alone components, without including a
framework script as a dependency - Svelte is a compiler, it’s only framework
during the build process
• Svelte can therefore be used to
• Swap out individual components
• Replace an entire app, up to you
• It works with the standard rather than trying to invent it. Svelte looks and feels
like just working with HTML, CSS and JS
WHAT
• One component per file
• Styles scoped by default
• It’s just HTML, CSS, JS
• Powerful features like expressive directives. Usual suspects like
Bindings, ability to
• watch changes,
• Input props,
• Events etc.
Show me code
// Hello.svelte
<script>
let name = 'world';
</script>
<h1>Hello {name}</h1>
/* App.svelte generated by Svelte v3.16.7 */
import {
SvelteComponent,
detach,
element,
init,
insert,
noop,
safe_not_equal
} from "svelte/internal";
function create_fragment(ctx) {
let h1;
return {
c() {
h1 = element("h1");
h1.textContent = `Hello ${name}!`;
},
m(target, anchor) {
insert(target, h1, anchor);
},
p: noop,
i: noop,
o: noop,
d(detaching) {
if (detaching) detach(h1);
}
};
}
let name = "world";
class App extends SvelteComponent {
constructor(options) {
super();
init(this, options, null, create_fragment, safe_not_equal, {});
}
}
export default App;
How to get started
• Svelte.dev, great site with interactive tutorial
• Create your own project,
• npx degit sveltejs/template hello-app
• npm install
• npm run dev
• Install extensions for eitherVim/VS Code
Interpolation, {}
<script>
let src = 'tutorial/image.gif’;
Let title =‘something’;
</script>
<img src={src}>
<div>{title}</div>
In an attribute
or
directly in the markup
A typical component
<style>
p {
color: purple;
font-family: 'Comic Sans MS', cursive;
font-size: 2em;
}
</style>
<script>
let src = 'tutorial/image.gif’;
let description = "Rick Astley"
</script>
<p>
<img src={src}>
<p>
<div>{description}</div>
Scoped styles
Code section
Markup + interpolation
Import & use a component
// App.svelte
<script>
import Nested from './Nested.svelte';
</script>
<p>Some text</p>
<Nested />
Import
Use
Render HTML
<script>
let string = `this string contains some
<strong>HTML!!!</strong>`;
</script>
<p>{@html string}</p>
@html string-containing HTML
HTML
Handle Events
<script>
let count = 0;
function handleClick() {
// event handler code goes here
count += 1;
}
</script>
<button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
Method declaration
Bind “handleClick” to “click” event with on:click
Additional event example: mousemove
<script>
let m = { x: 0, y: 0 };
function handleMousemove(event) {
m.x = event.clientX;
m.y = event.clientY;
}
</script>
<style >
div { width: 100%; height: 100%; }
</style>
<div on:mousemove={handleMousemove}>
The mouse position is {m.x} x {m.y}
</div>
Bind “handleMousemove” to “mousemove” event
with on:mousemove
Method declarationc
Inline handlers
<div on:mousemove={handleMove}>
</div>
<div on:mousemove={e => m = { x : e.clientX, y: e.clientY }}>
</div>
Lambda function
Reference to function
Event modifiers
<script>
function handleClick() {
console.log('only run once');
}
</script>
<div on:click|once={handleClick}>
I dare you click me more than once
</div>
• `preventDefault` — calls event.preventDefault() before running the
handler. Useful for client-side form handling, for example.
• `stopPropagation` — calls event.stopPropagation(), preventing the
event reaching the next element
• `passive` — improves scrolling performance on touch/wheel events
(Svelte will add it automatically where it's safe to do so)
• `capture` — fires the handler during the capture phase instead of the
bubbling phase ()
• `once` — remove the handler after the first time it runs
• `self` — only trigger handler if event.target is the element itself
Additionally you can chain modifiers like so
`on:event|modifier|secondModifier={handler}`
Modifier
Computed state
<script>
let count = 0;
function handleClick() {
count += 1;
}
$: doubled = count * 2;
</script>
<button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
{doubled}
Runs when count changes, calculates a new value for double
Reactive statements
<script>
let count = 0;
function handleClick() {
count += 1;
}
$: console.log(`Value changed ${count}`);
</script>
<button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
Runs when count changes, i.e can also run statements
Grouped reactive statements
<script>
let count = 0;
function handleClick() {
count += 1;
}
$: {
console.log(`the count is ${count}`)
alert(count)
}
</script>
<button on:click={handleClick}>
Clicked {count} {count === 1 ? 'time' : 'times'}
</button>
Can run several lines of code, using {}
Reactivity and assignments
Svelte triggers on assignments. This means that the
following code WONT update the UI:
array.push(1)
but this will:
array = [...array, 1]
Component input
// Nested.svelte
<script>
export let answer;
</script>
<p>The answer is {answer}</p>
<script>
import Nested from './Nested.svelte';
</script>
<div>something...</div>
<Nested answer={42} />
export keyword is used to expose answer
Component input – spread props
<script>
val obj = {
firstname: 'ada’,
lastname: 'lovelace’,
profession: 'programmer'
};
</script>
<Person firstname={obj.firstname} lastname={obj.lastname}
profession={obj.profession} > <Person {...obj} />
Component output
// Inner.svelte
<script>
import { createEventDispatcher } from 'svelte';
let dispatcher = createEventDispatcher();
function handleEvent() {
dispatcher.dispatch('message', {
text: 'An event’
})
}
</script>
<button on:click={handleEvent}>Fire event</button>
// App.svelte
<script>
import Inner from './Inner.svelte';
function handleMessage(event) {
alert(event.detail.text);
}
</script>
<Inner on:message={handleMessage}/>
Dispatch, to raise the event Name of the event Name of the event
Handle event
Forwarding an event
Inner Outer App
message messagemessage
// Inner.svelte
<script>
import { createEventDispatcher } from 'svelte';
let dispatcher = createEventDispatcher();
function handleEvent() {
dispatcher.dispatch('message', {
text: 'An event’
})
}
</script>
<button on:click={handleEvent}>Fire event</button>
// Outer.svelte
<Inner on:message />
// App.svelte
import Outer from './Outer.svelte';
function handleEvent(event) {
console.log(event.text);
}
</script>
<Outer on:message={handleEvent} />
No event handler
Just forward the
event
Directives
• IF ELSE, IF ELSE-IF ELSE
• FOR
• ASYNC/AWAIT
IF/ELSE
{#if user.loggedIn}
<button on:click={toggle}>
Log out
</button>
{:else}
<button on:click={toggle}>
Log in
</button>
{/if}
{#if <boolean>}
{:else <boolean>}
{/if}
IF/ELSE-IF/ELSE
{#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}
{#if <boolean>}
{:else if <boolean>}
:else <boolean>}
{/if
FOR-LOOPS
{#each todos as todo}
<div>{todo.name}</div>
{/each}
{#each todos as { name, id, done }}
<div>{todo.name}</div>
{/each}
{#each todos as todo(todo.id)}
// do stuff
{/each}
list item We can spread it
Point out the
unique property, so
it doesn’t do
unnecessary work
AWAIT BLOCK
<script>
let promise = getData();
function async getData() {
const res = await fetch(url);
const json = await res.json();
return json;
}
</script>
<div>
{#await promise}
<p>...loading</p>
{:then data}
<p>Render data {data}</p>
{:catch error}
<p>Error {error.message}</p>
{/await}
</div>
Construct the Promise.
We can capture the error
and rethrow if we need to
Wait for the Promise
Render data
Render error
Binding
<script>
let name = 'render me’;
Let yes = false;
</script>
<input bind:value={name} />
<input type=number bind:value={a} min=0 max=10>
<input type=checkbox bind:checked={yes}>
Coerces the string to be a
number
Binds to variable yes
Binds input to variable
name
Grouped bindings
<script>
let menu = [
'Cookies and cream’,
'Mint choc chip’,
'Raspberry ripple’
];
let flavours = [];
let selectedFlavour = '';
</script>
<h2>Pick many</h2>
{#each menu as flavour}
<label>
<input type=checkbox
bind:group={flavours}
value={flavour}>
{flavour}
</label>
{/each}
<h2>Pick one</h2>
{#each menu as flavour}
<label>
<input type=radio
bind:group={selectedFlavour}
value={flavour}>
{flavour}
</label>
{/each}
<div>
Selected Flavours: {flavours}
</div>
<div>
Selected flavour: {selectedFlavour}
Checkbox binds to array
[]
Radio binds to string
Other controls
<textarea bind:value={value}></textarea>
<select
bind:value={selected}
on:change="{() => answer = ''}">
{#each questions as question}
<option value={question}>
{question.text}
</option>
{/each}
</select>
<div
contenteditable="true"
bind:innerHTML={html}
></div>
Bind value to <select>
Bind to innerHTML
Loop out items
Working with lists (e.g TodoList)
• Mutate list bind:checked
• Immutable list, events
Mutating list with bind:checked
<script>
let todos = [
{ done: false, text: 'finish Svelte tutorial' },
{ done: false, text: 'build an app' },
{ done: false, text: 'world domination' }
];
function add() {
todos = todos.concat({ done: false, text: '' });
}
function clear() {
todos = todos.filter(t => !t.done);
}
$: remaining = todos.filter(t => !t.done).length;
</script>
<style>
.done {
opacity: 0.4;
}
</style>
<h1>Todos</h1>
{#each todos as todo}
<div class:done={todo.done}>
<input
type=checkbox
bind:checked={todo.done}
>
<input
placeholder="What needs to be done?"
bind:value={todo.text}
>
</div>
{/each}
<p>{remaining} remaining</p>
<button on:click={add}>Add new</button>
<button on:click={clear}>Clear completed</button>
{#each todos as todo}
<div>{todo.text} {todo.done}</div>
{/each}
Immutable list, event
<script>
let todos = [
{ done: false, text: 'finish Svelte tutorial' },
{ done: false, text: 'build an app' },
{ done: false, text: 'world domination' }
];
function add() {
todos = todos.concat({ done: false, text: '' });
}
function handleChanged(e, todo) {
console.log('changed', e.target.checked);
console.log('changed todo', todo)
}
function clear() {
todos = todos.filter(t => !t.done);
}
$: remaining = todos.filter(t => !t.done).length;
</script>
<style>
.done { opacity: 0.4; }
</style>
<h1>Todos</h1>
{#each todos as todo}
<div class:done={todo.done}>
<input
type=checkbox
on:change={(e) => handleChanged(e, todo)}
checked={todo.done}
>
<input
placeholder="What needs to be done?"
bind:value={todo.text}
>
</div>
{/each}
<p>{remaining} remaining</p>
<button on:click={add}>Add new</button>
<button on:click={clear}>Clear completed</button>
{#each todos as todo}
<div>{todo.text} {todo.done}</div>
{/each}
Routing
https://github.com/EmilTholin/svelte-routing
<script>
import Test from './Test.svelte';
export let name;
import { Router, Link, Route } from "svelte-routing";
import Home from "./routes/Home.svelte";
import About from "./routes/About.svelte";
import Blog from "./routes/Blog.svelte";
export let url = "";
</script>
<main>
<Router url="{url}">
<nav>
<Link to="/">Home</Link>
<Link to="about">About</Link>
<Link to="blog">Blog</Link>
</nav>
<div>
<Route path="blog" component="{Blog}" />
<Route path="about" component="{About}" />
<Route path="/">
<Home />
</Route>
</div>
</Router>
</main>
npm install --save svelte-routing
Testing - https://testing-library.com/docs/svelte-
testing-library/setup
Svelte Testing Library
npm install --save-dev @testing-library/svelte
Jest is recommended with it
npm install --save-dev jest
// package.json
{ "scripts": {
"test": "jest src",
"test:watch": "npm run test -- --watch"
}
}
npm install --save-dev svelte-jester
// package.json
{
"jest": {
"transform": { "^.+.svelte$": "svelte-jester" },
"moduleFileExtensions": ["js", "svelte”]
}
}
A test
// NOTE: jest-dom adds handy assertions to Jest and it is
recommended, but not required.
import '@testing-library/jest-dom/extend-expect’
import { render, fireEvent } from '@testing-library/svelte’
import Comp from '../Comp’
test('shows proper heading when rendered', () => {
const { getByText } = render(Comp, { name: 'World' })
expect(getByText('Hello World!')).toBeInTheDocument() })
// Note: This is as an async test as we are using `fireEvent`
test('changes button text on click', async () => {
const { getByText } = render(Comp, { name: 'World' })
const button = getByText('Button’)
// Using await when firing events is unique to the svelte testing library because
// we have to wait for the next `tick` so that Svelte flushes all pending state
changes.
await fireEvent.click(button)
expect(button).toHaveTextContent('Button Clicked') })
Summary
• Been around a while Created in 2016, now on version 3
• Is the new kid on the Block, yet another SPA framework?
• Easy to learn, its’ just HTML, CSS and JS
• Is a Compiler, so a framework at compile time
• Small footprint & fast no VDOM, at least as fast as the big three SPAs
• Tooling for VIM, VS Code
• Dependent on OSS libs, Router (3rd party) + Test lib in place
• Remaining questions, Ready for production? Should I use in production?

More Related Content

PDF
Svelte JS introduction
PDF
Svelte as a Reactive Web Framework
PDF
Pros & cons of svelte
PDF
Svelte the future of frontend development
PDF
Angular Observables & RxJS Introduction
PDF
React new features and intro to Hooks
PDF
React JS and why it's awesome
Svelte JS introduction
Svelte as a Reactive Web Framework
Pros & cons of svelte
Svelte the future of frontend development
Angular Observables & RxJS Introduction
React new features and intro to Hooks
React JS and why it's awesome

What's hot (20)

PDF
JavaScript Promises
PDF
Intro to vue.js
PDF
introduction to Vue.js 3
PPTX
Docker Basic to Advance
PDF
NodeJS for Beginner
PDF
Asynchronous javascript
PDF
Express node js
PPTX
react-slides.pptx
PDF
Introduction to thymeleaf
PDF
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
PDF
React js use contexts and useContext hook
PDF
Introduction to Node.JS Express
PPTX
PDF
Vue JS Intro
PDF
RESTful API Design & Implementation with CodeIgniter PHP Framework
PPTX
clean code book summary - uncle bob - English version
PPTX
JavaScript Event Loop
PDF
Top 50 Node.js Interview Questions and Answers | Edureka
PDF
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
PPTX
React - Start learning today
JavaScript Promises
Intro to vue.js
introduction to Vue.js 3
Docker Basic to Advance
NodeJS for Beginner
Asynchronous javascript
Express node js
react-slides.pptx
Introduction to thymeleaf
Node.js Express Tutorial | Node.js Tutorial For Beginners | Node.js + Expres...
React js use contexts and useContext hook
Introduction to Node.JS Express
Vue JS Intro
RESTful API Design & Implementation with CodeIgniter PHP Framework
clean code book summary - uncle bob - English version
JavaScript Event Loop
Top 50 Node.js Interview Questions and Answers | Edureka
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
React - Start learning today
Ad

Similar to Learning Svelte (20)

PPTX
Getting started with Svelte Presentation
PDF
svelte-en.pdf
PDF
ReactJS - frontend web developing reactjs
PDF
react hook and wesite making structure ppt
PDF
React Tech Salon
PDF
sveltekit-en.pdf
PDF
Intro to React - Featuring Modern JavaScript
PDF
Using React, Redux and Saga with Lottoland APIs
PDF
ReactJS for Programmers
PDF
Frontin like-a-backer
PDF
Workshop React.js
PDF
Web Development with Delphi and React - ITDevCon 2016
PDF
React - The JavaScript Library for User Interfaces
PDF
MeetJS Summit 2016: React.js enlightenment
PPTX
ReactJS.NET - Fast and Scalable Single Page Applications
PDF
Tech Talk on ReactJS
PPTX
From JSX to Deployment: Mastering the React Workflow for Scalable Front-End D...
PPTX
Reactjs notes.pptx for web development- tutorial and theory
PDF
Introduction to React for Frontend Developers
PPTX
Getting started with Svelte Presentation
svelte-en.pdf
ReactJS - frontend web developing reactjs
react hook and wesite making structure ppt
React Tech Salon
sveltekit-en.pdf
Intro to React - Featuring Modern JavaScript
Using React, Redux and Saga with Lottoland APIs
ReactJS for Programmers
Frontin like-a-backer
Workshop React.js
Web Development with Delphi and React - ITDevCon 2016
React - The JavaScript Library for User Interfaces
MeetJS Summit 2016: React.js enlightenment
ReactJS.NET - Fast and Scalable Single Page Applications
Tech Talk on ReactJS
From JSX to Deployment: Mastering the React Workflow for Scalable Front-End D...
Reactjs notes.pptx for web development- tutorial and theory
Introduction to React for Frontend Developers
Ad

More from Christoffer Noring (20)

PPTX
Azure signalR
PPTX
Game dev 101 part 3
PPTX
Game dev 101 part 2
PPTX
Game dev workshop
PPTX
Deploying your static web app to the Cloud
PPTX
IaaS with ARM templates for Azure
PPTX
PDF
Angular Schematics
PDF
Design thinking
PDF
Keynote ijs
PDF
Vue fundamentasl with Testing and Vuex
PDF
Ngrx slides
PDF
PPTX
Angular mix chrisnoring
PDF
Nativescript angular
PDF
Graphql, REST and Apollo
PDF
Angular 2 introduction
PDF
Rxjs vienna
PPTX
Rxjs marble-testing
PDF
React lecture
Azure signalR
Game dev 101 part 3
Game dev 101 part 2
Game dev workshop
Deploying your static web app to the Cloud
IaaS with ARM templates for Azure
Angular Schematics
Design thinking
Keynote ijs
Vue fundamentasl with Testing and Vuex
Ngrx slides
Angular mix chrisnoring
Nativescript angular
Graphql, REST and Apollo
Angular 2 introduction
Rxjs vienna
Rxjs marble-testing
React lecture

Recently uploaded (20)

PPTX
L1 - Introduction to python Backend.pptx
PDF
Upgrade and Innovation Strategies for SAP ERP Customers
PDF
Digital Strategies for Manufacturing Companies
PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PDF
How Creative Agencies Leverage Project Management Software.pdf
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 41
PDF
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
PDF
System and Network Administraation Chapter 3
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
top salesforce developer skills in 2025.pdf
PPTX
Introduction to Artificial Intelligence
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PPTX
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
ai tools demonstartion for schools and inter college
PDF
Design an Analysis of Algorithms II-SECS-1021-03
L1 - Introduction to python Backend.pptx
Upgrade and Innovation Strategies for SAP ERP Customers
Digital Strategies for Manufacturing Companies
Navsoft: AI-Powered Business Solutions & Custom Software Development
How Creative Agencies Leverage Project Management Software.pdf
Internet Downloader Manager (IDM) Crack 6.42 Build 41
Addressing The Cult of Project Management Tools-Why Disconnected Work is Hold...
System and Network Administraation Chapter 3
CHAPTER 2 - PM Management and IT Context
Operating system designcfffgfgggggggvggggggggg
top salesforce developer skills in 2025.pdf
Introduction to Artificial Intelligence
ISO 45001 Occupational Health and Safety Management System
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Oracle E-Business Suite: A Comprehensive Guide for Modern Enterprises
How to Choose the Right IT Partner for Your Business in Malaysia
Wondershare Filmora 15 Crack With Activation Key [2025
Odoo Companies in India – Driving Business Transformation.pdf
ai tools demonstartion for schools and inter college
Design an Analysis of Algorithms II-SECS-1021-03

Learning Svelte

  • 2. WHY • Less cruft/ boilerplate • It’s fast, no Virtual DOM • No script tag, Svelte bundles stand-alone components, without including a framework script as a dependency - Svelte is a compiler, it’s only framework during the build process • Svelte can therefore be used to • Swap out individual components • Replace an entire app, up to you • It works with the standard rather than trying to invent it. Svelte looks and feels like just working with HTML, CSS and JS
  • 3. WHAT • One component per file • Styles scoped by default • It’s just HTML, CSS, JS • Powerful features like expressive directives. Usual suspects like Bindings, ability to • watch changes, • Input props, • Events etc.
  • 4. Show me code // Hello.svelte <script> let name = 'world'; </script> <h1>Hello {name}</h1> /* App.svelte generated by Svelte v3.16.7 */ import { SvelteComponent, detach, element, init, insert, noop, safe_not_equal } from "svelte/internal"; function create_fragment(ctx) { let h1; return { c() { h1 = element("h1"); h1.textContent = `Hello ${name}!`; }, m(target, anchor) { insert(target, h1, anchor); }, p: noop, i: noop, o: noop, d(detaching) { if (detaching) detach(h1); } }; } let name = "world"; class App extends SvelteComponent { constructor(options) { super(); init(this, options, null, create_fragment, safe_not_equal, {}); } } export default App;
  • 5. How to get started • Svelte.dev, great site with interactive tutorial • Create your own project, • npx degit sveltejs/template hello-app • npm install • npm run dev • Install extensions for eitherVim/VS Code
  • 6. Interpolation, {} <script> let src = 'tutorial/image.gif’; Let title =‘something’; </script> <img src={src}> <div>{title}</div> In an attribute or directly in the markup
  • 7. A typical component <style> p { color: purple; font-family: 'Comic Sans MS', cursive; font-size: 2em; } </style> <script> let src = 'tutorial/image.gif’; let description = "Rick Astley" </script> <p> <img src={src}> <p> <div>{description}</div> Scoped styles Code section Markup + interpolation
  • 8. Import & use a component // App.svelte <script> import Nested from './Nested.svelte'; </script> <p>Some text</p> <Nested /> Import Use
  • 9. Render HTML <script> let string = `this string contains some <strong>HTML!!!</strong>`; </script> <p>{@html string}</p> @html string-containing HTML HTML
  • 10. Handle Events <script> let count = 0; function handleClick() { // event handler code goes here count += 1; } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> Method declaration Bind “handleClick” to “click” event with on:click
  • 11. Additional event example: mousemove <script> let m = { x: 0, y: 0 }; function handleMousemove(event) { m.x = event.clientX; m.y = event.clientY; } </script> <style > div { width: 100%; height: 100%; } </style> <div on:mousemove={handleMousemove}> The mouse position is {m.x} x {m.y} </div> Bind “handleMousemove” to “mousemove” event with on:mousemove Method declarationc
  • 12. Inline handlers <div on:mousemove={handleMove}> </div> <div on:mousemove={e => m = { x : e.clientX, y: e.clientY }}> </div> Lambda function Reference to function
  • 13. Event modifiers <script> function handleClick() { console.log('only run once'); } </script> <div on:click|once={handleClick}> I dare you click me more than once </div> • `preventDefault` — calls event.preventDefault() before running the handler. Useful for client-side form handling, for example. • `stopPropagation` — calls event.stopPropagation(), preventing the event reaching the next element • `passive` — improves scrolling performance on touch/wheel events (Svelte will add it automatically where it's safe to do so) • `capture` — fires the handler during the capture phase instead of the bubbling phase () • `once` — remove the handler after the first time it runs • `self` — only trigger handler if event.target is the element itself Additionally you can chain modifiers like so `on:event|modifier|secondModifier={handler}` Modifier
  • 14. Computed state <script> let count = 0; function handleClick() { count += 1; } $: doubled = count * 2; </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> {doubled} Runs when count changes, calculates a new value for double
  • 15. Reactive statements <script> let count = 0; function handleClick() { count += 1; } $: console.log(`Value changed ${count}`); </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> Runs when count changes, i.e can also run statements
  • 16. Grouped reactive statements <script> let count = 0; function handleClick() { count += 1; } $: { console.log(`the count is ${count}`) alert(count) } </script> <button on:click={handleClick}> Clicked {count} {count === 1 ? 'time' : 'times'} </button> Can run several lines of code, using {}
  • 17. Reactivity and assignments Svelte triggers on assignments. This means that the following code WONT update the UI: array.push(1) but this will: array = [...array, 1]
  • 18. Component input // Nested.svelte <script> export let answer; </script> <p>The answer is {answer}</p> <script> import Nested from './Nested.svelte'; </script> <div>something...</div> <Nested answer={42} /> export keyword is used to expose answer
  • 19. Component input – spread props <script> val obj = { firstname: 'ada’, lastname: 'lovelace’, profession: 'programmer' }; </script> <Person firstname={obj.firstname} lastname={obj.lastname} profession={obj.profession} > <Person {...obj} />
  • 20. Component output // Inner.svelte <script> import { createEventDispatcher } from 'svelte'; let dispatcher = createEventDispatcher(); function handleEvent() { dispatcher.dispatch('message', { text: 'An event’ }) } </script> <button on:click={handleEvent}>Fire event</button> // App.svelte <script> import Inner from './Inner.svelte'; function handleMessage(event) { alert(event.detail.text); } </script> <Inner on:message={handleMessage}/> Dispatch, to raise the event Name of the event Name of the event Handle event
  • 21. Forwarding an event Inner Outer App message messagemessage // Inner.svelte <script> import { createEventDispatcher } from 'svelte'; let dispatcher = createEventDispatcher(); function handleEvent() { dispatcher.dispatch('message', { text: 'An event’ }) } </script> <button on:click={handleEvent}>Fire event</button> // Outer.svelte <Inner on:message /> // App.svelte import Outer from './Outer.svelte'; function handleEvent(event) { console.log(event.text); } </script> <Outer on:message={handleEvent} /> No event handler Just forward the event
  • 22. Directives • IF ELSE, IF ELSE-IF ELSE • FOR • ASYNC/AWAIT
  • 23. IF/ELSE {#if user.loggedIn} <button on:click={toggle}> Log out </button> {:else} <button on:click={toggle}> Log in </button> {/if} {#if <boolean>} {:else <boolean>} {/if}
  • 24. IF/ELSE-IF/ELSE {#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} {#if <boolean>} {:else if <boolean>} :else <boolean>} {/if
  • 25. FOR-LOOPS {#each todos as todo} <div>{todo.name}</div> {/each} {#each todos as { name, id, done }} <div>{todo.name}</div> {/each} {#each todos as todo(todo.id)} // do stuff {/each} list item We can spread it Point out the unique property, so it doesn’t do unnecessary work
  • 26. AWAIT BLOCK <script> let promise = getData(); function async getData() { const res = await fetch(url); const json = await res.json(); return json; } </script> <div> {#await promise} <p>...loading</p> {:then data} <p>Render data {data}</p> {:catch error} <p>Error {error.message}</p> {/await} </div> Construct the Promise. We can capture the error and rethrow if we need to Wait for the Promise Render data Render error
  • 27. Binding <script> let name = 'render me’; Let yes = false; </script> <input bind:value={name} /> <input type=number bind:value={a} min=0 max=10> <input type=checkbox bind:checked={yes}> Coerces the string to be a number Binds to variable yes Binds input to variable name
  • 28. Grouped bindings <script> let menu = [ 'Cookies and cream’, 'Mint choc chip’, 'Raspberry ripple’ ]; let flavours = []; let selectedFlavour = ''; </script> <h2>Pick many</h2> {#each menu as flavour} <label> <input type=checkbox bind:group={flavours} value={flavour}> {flavour} </label> {/each} <h2>Pick one</h2> {#each menu as flavour} <label> <input type=radio bind:group={selectedFlavour} value={flavour}> {flavour} </label> {/each} <div> Selected Flavours: {flavours} </div> <div> Selected flavour: {selectedFlavour} Checkbox binds to array [] Radio binds to string
  • 29. Other controls <textarea bind:value={value}></textarea> <select bind:value={selected} on:change="{() => answer = ''}"> {#each questions as question} <option value={question}> {question.text} </option> {/each} </select> <div contenteditable="true" bind:innerHTML={html} ></div> Bind value to <select> Bind to innerHTML Loop out items
  • 30. Working with lists (e.g TodoList) • Mutate list bind:checked • Immutable list, events
  • 31. Mutating list with bind:checked <script> let todos = [ { done: false, text: 'finish Svelte tutorial' }, { done: false, text: 'build an app' }, { done: false, text: 'world domination' } ]; function add() { todos = todos.concat({ done: false, text: '' }); } function clear() { todos = todos.filter(t => !t.done); } $: remaining = todos.filter(t => !t.done).length; </script> <style> .done { opacity: 0.4; } </style> <h1>Todos</h1> {#each todos as todo} <div class:done={todo.done}> <input type=checkbox bind:checked={todo.done} > <input placeholder="What needs to be done?" bind:value={todo.text} > </div> {/each} <p>{remaining} remaining</p> <button on:click={add}>Add new</button> <button on:click={clear}>Clear completed</button> {#each todos as todo} <div>{todo.text} {todo.done}</div> {/each}
  • 32. Immutable list, event <script> let todos = [ { done: false, text: 'finish Svelte tutorial' }, { done: false, text: 'build an app' }, { done: false, text: 'world domination' } ]; function add() { todos = todos.concat({ done: false, text: '' }); } function handleChanged(e, todo) { console.log('changed', e.target.checked); console.log('changed todo', todo) } function clear() { todos = todos.filter(t => !t.done); } $: remaining = todos.filter(t => !t.done).length; </script> <style> .done { opacity: 0.4; } </style> <h1>Todos</h1> {#each todos as todo} <div class:done={todo.done}> <input type=checkbox on:change={(e) => handleChanged(e, todo)} checked={todo.done} > <input placeholder="What needs to be done?" bind:value={todo.text} > </div> {/each} <p>{remaining} remaining</p> <button on:click={add}>Add new</button> <button on:click={clear}>Clear completed</button> {#each todos as todo} <div>{todo.text} {todo.done}</div> {/each}
  • 33. Routing https://github.com/EmilTholin/svelte-routing <script> import Test from './Test.svelte'; export let name; import { Router, Link, Route } from "svelte-routing"; import Home from "./routes/Home.svelte"; import About from "./routes/About.svelte"; import Blog from "./routes/Blog.svelte"; export let url = ""; </script> <main> <Router url="{url}"> <nav> <Link to="/">Home</Link> <Link to="about">About</Link> <Link to="blog">Blog</Link> </nav> <div> <Route path="blog" component="{Blog}" /> <Route path="about" component="{About}" /> <Route path="/"> <Home /> </Route> </div> </Router> </main> npm install --save svelte-routing
  • 34. Testing - https://testing-library.com/docs/svelte- testing-library/setup Svelte Testing Library npm install --save-dev @testing-library/svelte Jest is recommended with it npm install --save-dev jest // package.json { "scripts": { "test": "jest src", "test:watch": "npm run test -- --watch" } } npm install --save-dev svelte-jester // package.json { "jest": { "transform": { "^.+.svelte$": "svelte-jester" }, "moduleFileExtensions": ["js", "svelte”] } }
  • 35. A test // NOTE: jest-dom adds handy assertions to Jest and it is recommended, but not required. import '@testing-library/jest-dom/extend-expect’ import { render, fireEvent } from '@testing-library/svelte’ import Comp from '../Comp’ test('shows proper heading when rendered', () => { const { getByText } = render(Comp, { name: 'World' }) expect(getByText('Hello World!')).toBeInTheDocument() }) // Note: This is as an async test as we are using `fireEvent` test('changes button text on click', async () => { const { getByText } = render(Comp, { name: 'World' }) const button = getByText('Button’) // Using await when firing events is unique to the svelte testing library because // we have to wait for the next `tick` so that Svelte flushes all pending state changes. await fireEvent.click(button) expect(button).toHaveTextContent('Button Clicked') })
  • 36. Summary • Been around a while Created in 2016, now on version 3 • Is the new kid on the Block, yet another SPA framework? • Easy to learn, its’ just HTML, CSS and JS • Is a Compiler, so a framework at compile time • Small footprint & fast no VDOM, at least as fast as the big three SPAs • Tooling for VIM, VS Code • Dependent on OSS libs, Router (3rd party) + Test lib in place • Remaining questions, Ready for production? Should I use in production?

Editor's Notes

  • #6: Uses rollup to bundle up your app Found VS Code extension to not work, not sure if it’s my machine or not? (other say it works for them)
  • #7: {} single brackets
  • #8: Three distinct areas, style, script and markup, resembles Vue on that
  • #9: Simple to use
  • #10: @html tag is used to render HTML, careful though
  • #11: on:click to bind methods to events
  • #12: on:event
  • #13: Lambda/inline if you only have tiny bit of logic that needs to be written
  • #14: Modifiers, a powerful way to configure your event bindings, stop the event, one-time execution and more.
  • #15: Computed state
  • #16: Can run statements when a variable change
  • #17: {} makes it possible to run more than one line of code.
  • #18: IMPORTANT, change of reference is how it track changes
  • #19: Export, is the keyword that you need to make something public
  • #20: You can spread props so you don’t haven to mention each and everyone by name
  • #21: Dispatch, raises the event First arg is the name of the message On:<name of message> createEventDispatcher is what we use to dispatch event, pub/sub
  • #22: Inner raises event. Outer just forwards event App actually handles it No handler = forwarding, On:message, no event handler specified, it just sends the message upwards
  • #23: How to do branching logic in the template
  • #24: {#if} curly brace, square bracket ot start {:} colon for middle state {/} slash when we end it
  • #25: {#if} curly brace, square bracket ot start {:} colon for middle state and else if instead {/} slash when we end it
  • #27: Great way to define asynchronous behavior, saves a few lines of code
  • #28: bind:attribute, creates a 2-way binding
  • #29: Grouped binding is about having a list of checkbox or radio buttons Checkboxes means we can select more than one so saved as a list Radio are mutually exclusive, so it only becomes one value
  • #30: Bind:value on input as well as select For select we need to loop out the items For content editable we bind to innerHTML
  • #31: 2 different approaches 1. One mutates the items in the list 2. The other relies on events, Use the one you feel ok with.
  • #32: Bind:checked, ensure the attribute on an item is chan Changed automatically
  • #33: On:change if we want to handle it by events
  • #34: NOT built in but there are many 3rd part options. I find this one to work well for me Link, is how we navigate Route is how we specify what path gets rendered by what component
  • #35: For testing it’s about Surface testing NPM install the test lib JEST is recommended Recommended to set up script tasks for running and watching tests Must set up Jest though if used Have read through the docs for best practices
  • #36: Idea is to assert that elements exist with certain content Easy to trigger events, NOTE the await keyword on firing an event