How I rewrote my project in Svelte

Greetings to all. For a week now I have been rewriting my project, which was on the Vue options api using Quasar, and translating it to Svelte-Sveltkit-DaisyUI. I will say right away that I really liked it, especially considering that the Vue composition api has become more similar to React than to itself. It seems that Svelte is what Vue should have come to, but it came to react (you had to fight…).

So, the code that I wrote in view (wui in the common people) for 10 months in svelt was written in 9 days, and then I managed to add additional functions. Something has not yet been implemented, but this is the easy part, which will take 3-4 days, no more. Then binding to the backend and testing, and in 2-3 weeks everything should be generally ready. In fairness, it should be noted that not all of the time from these 10 months was used to write code. Half of the time was spent in fruitless attempts (torture) to write the backend myself. I jumped from one technology to another, but mostly I tried (tried myself) to write in fsharp. Nothing worked, I switched to node-express. Something came out, but in the process of writing I realized that the backing was not mine. One backender said that the work of a backender is like solving sudoku at work for 8 hours, and the rest of the time solving sudoku for leisure :-). I completely agree with this. The main thing is that I realized in time my inability to write a backend, and at the same time my dislike for solving Sudoku. Although when I was at school I loved it, probably the back would have come in at that time, but not a fact. From now on, if I ever write backing for something, I will only use ready-made things like strapi or directus.

It is also worth noting that when rewriting I already had experience and code from the project to view. But on swelt, everything would be faster even despite this, because swelt has many killer features that I either removed or didn’t have, as well as brevity and brevity of syntax and an abundance of simple sugar.

Here I will list those killer features that Svelte has, but which Vue does not have, or it is inconvenient.

Changing props

The most important feature for me personally is the ability to change component props. This is what I was missing from the view and why I didn’t switch to the compositing api (not only because it looks like React). View Options API, although it forbade changing props, but by reference to an object or array in props, it was possible to change its properties and get reactivity when something changes. Although it is still not possible to change spans by variable name in view, this has greatly reduced my code.

Svelt provides two ways to pass props and one of them, you guessed it, allows you to change props no matter what, be it an object, an array, or a variable with a simple type like a string.

<script>
  import Component from "./Component.svelte"
  const name="John Smithf"
  let count = 0;
  let config = {
    width: 10,
    height: 20,
    top: 0,
    left: 0
  }
</script>
<Component
           bind:count
           bind:config
           {name}>
  
<!--   Component.svelte -->
  <script>
  export let name;//Это неизменяемый пропс
  export let count, config;//Этих двоих уже можно изменить, и в родителе они тоже изменятся
  let increment = () => {
    count++
  }
  let changeConfig = () => {
    //Some code
  }
  </script>
  <h1>{name}</h1>
  <button on:click={increment}>{count}</button>

I don’t know about you, but in every project I faced the need to change the props. With view, the code turned out to be just terrible, unreadable and large. I was afraid that only I would be able to read this code, but with the easy svelt syntax, this is no longer a problem.

Also, with the addition of mutable props, I can now split my multi-ton code into even more components, where each is responsible for his own. And no typescript is needed. Honestly, I hate typescript. I agree that in a team, typescript can be of some use, but for a single person it only brings pain and a decrease in development speed.

use effect

React has a miracle user effect. View also has computed, but for some reason it was in my code that I had to invent all sorts of things to make it work. He did not want to understand what to do (or simply did not want to do). This is not the case with swelt. And unlike the React user-effect, there is no need to specify which variable to react to change. The compiler itself looks and analyzes.

<script>
let count = 0;
let count2 = 0;
let sqr;
$: sqr = count * count; //Реагирует когда count меняется
$: sqr = count + count2; //Этот уже реагирует когда один из двух коунтов меняется. Нет нужды указывать за каким следить
 </script>
  

This reduced my code, which was just in view at times.

Each instead of v-for :key

There is the most important minus svelt, truly what was in view. This ability – the “killer” feature in the view can be passed to vFor as an iterable object or just a number

and it worked. And I was surprised when I couldn’t do it in swelt.

Well, OK. Perhaps no one except me has ever used this feature, or maybe yes. Either way can be easily replaced with Object.keys or .entries and [0,1,2,3,4,5].

{#each Object.entries as [name, value], id}
<div>{id} {name} : {value}</div>
{/each}

{#each [0,1,2,3,4,5] as value, id}
<div>{id} {value}</div>
{/each}

So I still learned something from Shemseddinov’s courses))) I’ll have to finish it off)))

If-elseIf-else, await, store, events

Well, I think there is no need to list all this. So it is clear that if is an analogue of v-if from view. Well, I haven’t worked with await yet, although it’s clear what it does. I hope that it is as convenient as everything else. It is worth noting that the selection of logical elements into separate tag similarities made the code more readable than the attribute of the view.

Stores are no different from React, but the syntax makes them a pleasure to use.

Events in the view required $event to be passed explicitly, but svelt passes this parameter by default, and only requires explicit passing when there are other parameters.

<script>
  let handleClick = (ev) => {
    console.log(ev)
  }
  let handleClickWithParams = (ev, param) => {
    console.log(ev, param)
  }
</script>
<button on:click={handleClick}>Click</button>
<button on:click={ev=>handleClickWithParams(ev, param)}>handleClickWithParams</button>

I did not use event emitters from the component to the parent. At first, due to ignorance, I had to write on them, but with the realization of all of the above, I simply deleted them as unnecessary, otherwise they would litter the code. Seriously, with the power of all of the above, I did not see where I can use them in my code, although there are undoubtedly such tasks.

special elements

Svelt has additional goodies in the form of window, head, body elements, etc., which can only be accessed from the component through the house. These elements allow you to change their attributes directly from the component or page.

<svelte:head>
  <title>Главная</title>
</svelte:head>

Although there are elements that are not there, or features that were promised to fail, such as in order to dynamically change lang or data-theme attributes, as said Here. Or the ability to add html elements right inside the element as requested Here. All in all, this is very helpful.

Working with DOM and onMount

There are basic hooks in swelt, but they are not really needed. On the view, I constantly used onMount, however, in the svelt code, it starts up on its own and there is no need to use hooks without special need. OnMount can be useful if you need to work with the DOM. Since SveltKit is SSR by default, my code where I wanted to refer to document or window broke. I found two ways. The first is onMount, since it only runs in the browser and has all the objects. But I dismissed this method for its inconvenience.

The second way is to check whether these objects exist at all. But if(document), if(window) still caused errors. The exit has been found

<script>
  import { browser } from '$app/environment';
  let elem;
  if(browser)elem = document.getElementById();//Some code

  $: if(browser)document.querySelector('.active').style.color="red";
</script>

This method was found by me the most convenient for my tasks.

Passing variables dynamically in css

Working with the view, I somehow needed to change the css right in the