Svelte.js technology what it does and how it’s implemented (2)

1. Loop statements

This is definitely something we can’t do without, and svelte.js gives us an interesting way to write it.

<script>
  const arr = ['x1', 'x2', 'x3'];
</script>

<ul>
  {#each arr as item}
    <li>{item}</li>
  {/each}
</ul>

While svelte.js does not have a virtual DOM, it does require a key to loop, which is a little special.

<script>
  const arr = ['x1', 'x2', 'x3'];
</script>

<ul>
  {#each arr as item, i (i)}
    <li>{i} --- {item}</li>
  {/each}
</ul>

The (I) above is the key value, I is the ordinal and must be used, separated from item.

What does the loop compile to



Initializing just one variable doesn’t mean anything.

CTX in FIG. 2 is a prime group, CTX [0] is our defined ARR, and CTX [1] is the value corresponding to the current LI.

How does the loop handle the key

Here is the compiled code for the loop body with the key set.

Let’s focus on how the key works when we update dom data.

In fact, svelte.js also needs diff algorithm to update dom, this point should be clear.

4. Parent and child components

The parent component

/src/App.svelte

<script> import Son from './ subcomponent.svelte '; const options = { msg: 'xxxxxx', }; Const footer = {footer1: 'footer1', footer2: 'footer2',}; Function handleEmit(res) {console.log(' corresponding event 1', res); Console. log(' corresponding event 2', res.detail); </script> <div> <p> </p> <Son {options} {... footer} on:emit={handleEmit} /> </div>
Child components

/ SRC/subcomponent.svelte

<script> import { createEventDispatcher } from 'svelte'; export let options; export let footer1; export let footer2; Const Dispatch = createEventDispatcher(); Function emit() {dispatch('emit', {MSG: 'hello ',}); } < / script > < div > < p > child components: {options. MSG} < / p > < p > footer1: {footer1} < / p > < p > footer2: {footer2}</p> <button on:click={emit}> </button> </div>
  1. Subcomponent directimportYou can use it by introducing a child component.
  2. Parent components pass parameters between lines, child componentsexportTo receive.
  3. The parent component can pass parameters using extension operators.
  4. The parent componenton:emit={handleEmit}Listens for events published by a child component.
  5. Child component introductioncreateEventDispatcherImplement the publication of events.
  6. The child component can change the value passed to it without affecting the value in the parent component (Focus on).
  7. A change in the value passed by the parent to the child rerenders the child.

5. Package analysis of parent and child components

Style of six.

In svelte.js the styles are sandboxed by default, which means that the styles we write in a.svelte file do not permeate the whole world. One of the things that’s nice and convenient is that we’re not concatenating it as a template string, which is a nice way to write styles.

<script> const color = 'red'; const isBlack = true; <div> <p style="color:{color}" class: {isBlack}> <div style> p {color: blue; color: blue; font-size: 29px; font-weight: 800; } .black { border: 1px solid black; } </style>

Class :black={isBlack} class:black={isBlack}

If you want to set the global style you canhtmlormain.jsFile to import.

Vii. Life cycle

The concept of a lifecycle is now available to almost all libraries, and Svelte does a good job of it.

<script>
  import { onMount, onDestroy, beforeUpdate, afterUpdate } from 'svelte';

  onMount(() => {
    console.log('mounted');
  });

  onDestroy(() => {
    console.log('onDestroy');
  });

  beforeUpdate(() => {
    console.log('beforeUpdate');
  });

  afterUpdate(() => {
    console.log('afterUpdate');
  });
</script>
  1. onMountRuns after the component has been rendered to the DOM for the first time.
  2. onDestroyCalled when a component is destroyed.
  3. beforeUpdateRun before the DOM update.
  4. afterUpdateRun after DOM update.

Note that the lifecycle can be invoked multiple times as follows:

  onMount(() => {
    console.log('mounted1');
  });

  onMount(() => {
    console.log('mounted2');
  });

8. Asynchronous requests

For example, if we want to write loading effects for different DOM blocks, we need n loading variables. The following method will allow us to define fewer variables.

<script> function ajax() {return new Promise((res) => {setTimeout(() => {res(' request succeeded '); }, 1000); }); } </script> <div> {#await ajax()} <p>... loading</p> {:then res} <p> res: {res} </p> {/await} </div>

The effect is that loading is displayed in the request. After the request is completed, you can also add a {:catch err} tag, but it is not very good to handle errors here.

What the packaged code looks like

inhandle_promiseMethod, if it decides that we’re passing in a promise, executes the promise for us and assigns the result to it, and it has other complicated operations that we don’t have to go into.

What looks like a practical way to write it is not very practical.

Compute attributes

You can mark a statement with an identifier in JavaScript, as follows: $: foo = bar. It adds an identifier named $to the foo = bar statement (an error occurs in strict mode if foo is not previously defined).


So in this case, when Svelte sees any statements prefixed with $:, it knows that the variables on the left are getting their values from the variables on the right. We now have a way to bind the value of one variable to another.

We can take advantage of this, and develop our own compiler to create new syntax rules:

Use of computed attributes:
<script> let n = 1; $: nn = n * 2; function addn() { n++; } < / script > < div > < button on: click = {addn} > once ordered {nn} < / button > < / div >

So nn is always going to be equal to n times 2.

How is it implemented after packaging

X. Observer

<script> let n = 0; $: {const titel = 'n with the value: '; console.log(titel + n); $: if (n > 5) {alert('n > 5'); $: if (n > 5) {alert('n > 5'); } function addn() { n++; } < / script > < div > < button on: click = {addn} > once ordered {n} < / button > < / div >

  1. The initial braces are executed once by default.
  2. A change in the value in curly braces causes the entire code in curly braces to execute once.
  3. $:You can identify conditional statements.
The packaged code

I have to hand it to Svelte for doing a great job with identifiers.

Xi. Animation

First: Built-in animation (fade in and out)
<script> import { fade } from 'svelte/transition'; let visible = true; function change() { visible = ! visible; < span style = "box-sizing: border-box; color: RGB (50, 50, 50); line-height: 20px; font-size: 14px! Important; word-break: inherit! Important;"
  1. The first is to introduce animationfade.
  2. Tags definedtransition:fade.
The second kind of custom animation
<script> import { elasticOut } from 'svelte/easing'; let visible = true; function change() { visible = ! visible; } function whoosh(node, params) {const existingTransform = getComputedStyle(node).transform.replace('none', "); return { delay: params.delay || 0, duration: params.duration || 400, easing: params.easing || elasticOut, css: (t, u) => `transform: ${existingTransform} scale(${t})`, }; < span style = "box-sizing: border-box; color: RGB (0, 0, 0); line-height: 22px; font-size: 14px! Important; word-break: inherit! Important;"
  1. in:whooshThe animation is specified using the whoosh function.
  2. whooshThe return is the delay time of the animation, execution time, CSS effect, and so on.

I won’t talk about the package here.

Input box bidirectional binding

<script>
  let value = '';
</script>

<div>
  <input type="text" bind:value />
  <p>value: {value}</p>
</div>

The packaged file

It’s also tough. It’s just

13.vueUse insidesveltecomponent

One of the advantages of Svelte is that it is cross-platform and can be used in any framework because it is native JS code. Here’s how we can use it in a Vue project.

<script> let n = 0; function addn() { n++; Console. log(' triggered :addn'); } < / script > < div > < button on: click = {addn} > once ordered {n} < / button > < / div >

/src/main.js

import App from './App.svelte';
export default App;

After the yarn build, copy the bundle.js file into the index.js folder named XXX and put it into the node_modules of the target project. This is to simulate the real use scenario.

The index.js file we need to process to make it easier to export.

Conversions,

modified

Specific use mode
<script> import xxx from "xxx"; Export default {name: "App", mounted() {new XXX ({target: document.body, // insert the element and the initial value}); }}; </script>

Xiv. Technology selection

For example, I have introduced Vue runtime, so there is no need to use this technology. However, if you have developed some components with Svelte that are particularly compatible across platforms, you can still consider using Svelte. This will make it easier for both React and Vue to use your components.

Note that svelte does have advantages when the project size is small, but when the logic is complex, it is not easy to use. We can see from the way the package file is written that it is bound to have a lot of logic code after packaging, so the performance is not necessarily better than the runtime form after a certain amount of logic.

end.

This time is like this, I hope to make progress with you.