svelte tutorial logic

Conditional logic

Conditionally render some elements, using the "if" code block:

<script>
    let user = { loggedIn: true };

    function toggle() {
        user.loggedIn = !user.loggedIn;
    }
</script>

{#if user.loggedIn}
    <button on:click={toggle}>
        Log out
    </button>
{/if}

Using else code blocks

<script>
    let user = { loggedIn: false };

    function toggle() {
        user.loggedIn = !user.loggedIn;
    }
</script>

{#if user.loggedIn}
    <button on:click={toggle}>
        Log out
    </button>
{:else}
    <button on:click={toggle}>
        Log in
    </button>
{/if}

Multiple conditions can use else if:

<script>
    let x = 7;
</script>

{#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}

Cyclic logic

Each can traverse arrays, class array objects, and Iterable objects each [...iterable].

<script>
  let list = [{ name: "aaa" }, { name: "bbb" }, { name: "ccc" }];
</script>

{#each list as l}
  <p>This is {l.name}</p>
{/each}

Use list to render the contents of the else block in space-time.

<script>
  let list = [];
</script>
{#each list as l}
  <p>This is {l.name}</p>
{:else}
  <p>The list is empty</p>
{/each}

By default, when you modify the value of each block, it adds and deletes items at the end of the block, and updates all changed values. That may not be what you want. Looking at the following example, you will find that the last element is deleted, but what we actually want to delete is the first one.

// Thing.svelte
<script>
    // `current` is updated whenever the prop value changes...
    export let current;

    // ...but `initial` is fixed upon initialisation
    const initial = current;
</script>

<p>
    <span style="background-color: {initial}">initial</span>
    <span style="background-color: {current}">current</span>
</p>

<style>
    span {
        display: inline-block;
        padding: 0.2em 0.5em;
        margin: 0 0.2em 0.2em 0;
        width: 4em;
        text-align: center;
        border-radius: 0.2em;
        color: white;
    }
</style>
<script>
  import Thing from "../components/Thing";
  let things = [
    { id: 1, color: "#0d0887" },
    { id: 2, color: "#6a00a8" },
    { id: 3, color: "#b12a90" },
    { id: 4, color: "#e16462" },
    { id: 5, color: "#fca636" }
  ];
  function handleClick() {
    things = things.slice(1);
  }
</script>

<button on:click={handleClick}>
    Remove first thing
</button>

{#each things as thing}
    <Thing current={thing.color}/>
{/each}

In order to delete the specified element, we need to add a unique identifier key to the element:

<script>
  import Thing from "../components/Thing";
  let things = [
    { id: 1, color: "#0d0887" },
    { id: 2, color: "#6a00a8" },
    { id: 3, color: "#b12a90" },
    { id: 4, color: "#e16462" },
    { id: 5, color: "#fca636" }
  ];
  function handleClick() {
    things = things.slice(1);
  }
</script>

<button on:click={handleClick}>
    Remove first thing
</button>

{#each things as thing (thing.id)}
    <Thing current={thing.color}/>
{/each}

Sometimes we also need to use indexes.

// Thing.svelte
<script>
    // `current` is updated whenever the prop value changes...
    export let current;
  export let index;
    // ...but `initial` is fixed upon initialisation
    const initial = current;
</script>

<p>
    <span style="background-color: {initial}">initial {index}</span>
    <span style="background-color: {current}">current {index}</span>
</p>

<style>
    span {
        display: inline-block;
        padding: 0.2em 0.5em;
        margin: 0 0.2em 0.2em 0;
        width: 4em;
        text-align: center;
        border-radius: 0.2em;
        color: white;
    }
</style>
<script>
  import Thing from "../components/Thing";
  let things = [
    { id: 1, color: "#0d0887" },
    { id: 2, color: "#6a00a8" },
    { id: 3, color: "#b12a90" },
    { id: 4, color: "#e16462" },
    { id: 5, color: "#fca636" }
  ];
  function handleClick() {
    things = things.slice(1);
  }
</script>

<button on:click={handleClick}>
    Remove first thing
</button>

{#each things as thing, i (thing.id)}
    <Thing current={thing.color} index={i}/>
{/each}

Asynchronous data

svelte can also process asynchronous data.

<script>
  let num = 0;
  let promise = getNumber();
  function sleep(duration) {
    return new Promise(function(resolve, reject) {
      setTimeout(resolve, duration);
    });
  }
  async function getNumber() {
    await sleep(3000)
    if (num < 10) {
      return num;
    } else {
      throw new Error(`The ${num} is too big`);
    }
  }
  function handleClick() {
    num += 1;
    promise = getNumber();
  }
</script>

<button on:click={handleClick}>btn</button>
{#await promise}
  <p>...waiting</p>
{:then value}
  <p>The number is {value}</p>
{:catch error}
  <p style="color: red">{error}</p>
{/await}

If you do not want any data to be realistic before the promise solution call:

{#await promise then value}
  <p>The number is {value}</p>
{:catch error}
  <p style="color: red">{error}</p>
{/await}

If it is determined that reject will not be performed, catch:

{#await promise then value}
  <p>The number is {value}</p>
{/await}

All the code in this tutorial is uploaded to github for reference https://github.com/sullay/svelte-learn.

Keywords: Javascript github less

Added by FrankA on Wed, 09 Oct 2019 04:18:08 +0300