Reactive user interfaces using SvelteJS6 min read

Today I’ll be writing about SvelteJS.

A truly refreshing Javascript framework (Well, Svelte is not a framework. It’s a compiler.) which will, as stated on Svelte.dev web, enhance you web apps.

But I must say, not just your web apps, your whole experience of developing, will be enhanced.

Only few..ermmm, frameworks (should I call it a framework, NO!!!) blew my mind and this is one of them.

Why is that the case?

Let’s sum up the whole framework in a few bulletins and then I’ll show you some examples:

  1. fast when executing
  2. easy to grasp
  3. reactive without any fuss

Fast when executing

Since it’s not a framework but a compiler, it compiles our code and makes the most optimized Javascript code as a result.

It does not have virtual DOM.

Comparing it with other frameworks, you will see soon enough how small the production output of .js file really is.

Just try and compare it with React, VueJS or Angular when starting the blank project.

So here is a small task for you:

Take a look at the kb you get without writing any custom code!

With SvelteJS, blank project is roughly around 4kb. So, compare that to other frameworks!

Easy to grasp

Well, it really is EASY to get into Svelte world and the documentation is pretty solid.

But real magic happens when you start to dive into Svelte by writing apps. That was when I got blown away.

Svelte is component based, as any other framework.
You write everything into one file, just like in VueJS/React i.e.:

// app.svelte file
<script>
  // this is where all of your code for the app component goes in
</script>

<stlye>
  // here you do the stylings
</style>

<div>
  // plain html stuff goes here
</div>

Writing a component is easy. Just name a file i.e. Button.svelte and then you need to import it into other component.

// other.svelte file
<script>
	import Book from './Book.svelte';
</script>

If you, for instance, want to send text inside button component, we use plain html syntax (slot) i.e.

// custom.svelte file
<script>
  import Button from "./Button.svelte";
</script>

<Button>Some text</Button>
// Button.svelte 
<button>
  <slot/>
</button>

Component communication using props

Defining a props is pretty simple. Just add export in front of a variable you want to behave as a prop or input for a component.

// Book.svelte file
<script>
  export let bookTitle; // makes this as a props - an input for this component
  export let bookAuthor; // makes this as a props - an input for this component
  export let bookDescription; // makes this as a props - an input for this component
</script>
<div>
  <h1> {bookTitle} </h1>
  <h1> {bookAuthor} </h1>
  <h1> {bookDescription} </h1>
</div>

This way we can then use our Book component inside other custom component like this:

<script>
	import Book from './Book.svelte';
</script>
<div>
    <Book bookTitle="title 1" bookAuthor="author name" bookDescription="lorem ipsum" />
</div>

Let’s talk about binding.
We use curly { } braces to output or send values as input to other components.

// we bind model so we could output variable value here
<input type="text" id="title" value="{bookTitle}"/> 

// we bind event listeners (click, blur, input..) using normal html syntax with 'on:' 
// this is an example of two way binding
<input type="text" id="title" value="{bookTitle}" on:input="{nameOfJavascriptFunction}"/> 

// above example can be simplified with "bind" directive
<input type="text" id="title" bind:value="{bookTitle}"/>   

If you want to communicate between components(i.e.Button and Book) component, the easiest way would be by using dispatch.

  • Step 1. we set trigger on, without a pointer to any function
  • Step 2. in Book component we use that same trigger to dispatch any value
  • Step 3. we subscribe to an event dispatched, in a component we want to catch that event with value
// Step 1.
// Button.svelte component
<button on:click>
    <slot/>
</button>
// Step 2.
// Book.svelte file
<script>
    import {createEventDispatcher} from 'svelte';
    import Button from './Button.svelte';
    
    export let bookTitle;
    export let bookAuthor;
    export let bookDescription;

    const dispatch = createEventDispatcher();

    function showAuthorBooks() {
        dispatch('showauthorbooks', bookAuthor);
    }
</script>
<div>
    <h1> {bookTitle} </h1>
    <h2> {bookAuthor}</h2>
    <p> {bookDescription} </p>
    <Button on:click="{showAuthorBooks}">Show all author books</Button>
</div>
// Step 3.
// Custom.svelte file
<script>
import Book from "./Book.svelte";
function addToCart(event){
   const bookAuthor = event.detail;
}
</script>

<Book showauthorbooks="{showAuthorBooks}"/>

Arrays handling

Svelte only updates when we have ‘=‘ sign to a variable.
So if we initialized array like:

 books = [];

we set variable books with pointer to an array.
It will only update books but not the pointer to array.
So when we use:

books.push(value) 

it wont automatically update books.
The solution for this is to use array.concat ie.:

books = books.concat(newBook);

As i said before, this way by using ‘=’ we assign the value to an array and array get’s updated.

Reactive without any fuss

Dynamic / Labeled statements

These statements are used for computing values. As soon as we declare it after $: , that declaration becomes variable which can be used inside component. Hence, reactivity!

<script>
// labeled statements
// in svelte will be used to reexecuted when inputs changes
$: calculatedItems= items.reduce((sum, curValue) => {
    return sum + curValue.price;
},0)
</script>

<h1>Calculated value: ${calculatedItems}</h1>

Templating

When mixing code with html in Svelte, we use syntax like this:

{#if items.length === 0}
    <p>No items in cart yet.</p>
    {:else}
    <ul>
    {#each items as item}
        <li>{item.title} - ${item.price}</li>    
    {/each}
    </ul>
{/if}

For more examples, please take a look at Svelte documentation.

Animating html elements

Easy, just see this example:

<p in:fly={{ x: 2000, duration: 500}} out:fly={{ x:-500, duration:500}}>
 Some text that will appear using fly in and disappear using fly out animation
</p>

Using promises

This is just a simple overview of how it work’s in Svelte.

First create logic behind promise.

<script>
  function myPromise() {
    return new Promise();
  } 
  let customPromise = myPromise().then(r=>Math.random());
</script>

Secondly, show results of promise inside template.

{#await customPromise}
 <p> show while promise is resolved</p>
{:then calculatedNumber}
 <p> show result of resolved promise: {calculatedNumber} </p>
{:catch error}
 <p> {error.message}
{/await}

Conclusion

This is only tip of an iceberg.
As you can see, Svelte is joy to use. I will surely cover it up more in upcoming posts.


If you want to get more into Svelte, subscribe to mailing list to get notified of my upcoming video course about it!

Leave a Reply

Your email address will not be published. Required fields are marked *