iT邦幫忙

2023 iThome 鐵人賽

DAY 18
0
Modern Web

了不起的 Svelte系列 第 18

第 18 天:Svelte 中的邏輯運作:`each` 邏輯區塊(三)

  • 分享至 

  • xImage
  •  

第 18 天:Svelte 中的邏輯運作:each 邏輯區塊(三)

差不多在這個時候,一位滿懷抱負的年輕記者在某天早晨來到 Svelte 家門口,採訪他是否有什麼項目要擺在陣列裡頭。
「關於哪個陣列要擺放哪些項目?」Svelte 先生禮貌的反問。

~節錄自《The Great Svelte:第六章》

第 18 天要講的是

  1. 增加 {:else} 處理空陣列情形

  昨天我們用 each 邏輯搭配加減按鈕的事件設定,成功做出隨著使用者喜好改變色票數量的色票產生器了。同時我們把色票的數量限制在 16 之間,若是使用者利用計數器改變色票數量超過我們允許的範圍時,互動視窗就會跳出來提醒使用者。用這個做法就可以避免當色票數量變成 0 時,畫面上空空如也的情況,如圖一。

https://i.ibb.co/KNvJptj/18.gif
圖一、空空的色票數量 0

  這樣子做好像也不差?不過我們今天要來介紹的是,如何特別處理陣列數量為 0 的情形。

增加 {:else} 處理空陣列情形

  因為 each 段落是從陣列出發,藉由迭代陣列內的項目去一一產生 HTML 的元素,當然很有可能碰到陣列為空陣列的情況。所以 Svelte 也特別提供方法來處理空陣列的情形:

{#each array as item}
  <p>{item}<p>
{:else}
  <p>No item in the array.</p>
{/each}
  • 第一行:{#each array as item}
      用 {#each} 開始 each 段落的迭代。

  • 第二行:<p>{item}<p>
      若 array 這個陣列當中有項目,就一一顯示項目內容。

  • 第三行:{:else}
      選擇性的搭配一個 {:else} 邏輯段落,用來處理 array 為空陣列的情形。

  • 第四行:<p>No item in the array.</p>
      若陣列為空陣列,則顯示 {:else} 段落內的內容。

  • 第五行:{/each}
      用 {/each} 結束整個 each 邏輯段落。

  當迭代的陣列變成空陣列時,這個新增加的 {:else} 段落就會站出來補上空缺。語法的概念很像是:如果陣列當中有項目,就用 {#each} 去迭代陣列產生 HTML 元素。如果陣列當中沒有項目了,就用 {:else} 去產生 HTML 元素。最後用 {/each} 結束這個邏輯段落。
  雖然我們目前只先學到了 each 這個邏輯段落,不過大家可以先留意一下,在 Svelte 提供的邏輯段落裡,會常常使用這樣子的語法設計:用 {#} 展開邏輯段落,用 {:} 延續邏輯段落,用 {/} 結束邏輯段落。

  按照慣例,我們介紹了新的一個語法,今天也試著應用在我們的專案上面吧。為了能讓空陣列能夠發生,也就是我們的 palettes 這個陣列需要能被清零,首先要到 App.svelte 修改 tobeCount 允許的範圍:

/src/App.svelte
<script>
  import Counter from "./lib/Counter.svelte";
  import Modal from "./lib/Modal.svelte";
  import Palettes from "./lib/Palettes.svelte";

  let showModal = false;

  let palettes = [
    { hex: "ff4000", locked: false, id: "init_01" },
    { hex: "32e6e3", locked: false, id: "init_02" },
    { hex: "009fe9", locked: false, id: "init_03" },
  ];

  $: count = palettes.length;

  const generateTone = () =>
    ("0" + Math.round(255 * Math.random()).toString(16)).slice(-2);
  const generateHex = () =>
    [generateTone(), generateTone(), generateTone()].reduce(
      (a, c) => a + c,
      ""
    );
  const generatePalette = (() => {
    let uuid = 0;
    return () => ({
      hex: generateHex(),
      locked: false,
      id: `${uuid++}`,
    });
  })();

  let someState = "TheGreatSvelte";
  const sparkle = (text) => {
    const sparkles = ["★", "☆", "✧", "✪"];
    const randomSparkles = () =>
      sparkles[Math.floor(Math.random() * sparkles.length)];
    const sparkledText = text
      .split("")
      .reduce((a, c) => a + randomSparkles() + c, "");
    return sparkledText;
  };

  const href = "https://ithelp.ithome.com.tw/users/20120178/ironman/7031";

  const handleClick = (e) => {
    console.log(e);
    const tobeCount = count + e.detail;
    if (0 <= tobeCount && tobeCount < 7) {
      switch (e.detail) {
        case 1:
          palettes = [...palettes, generatePalette()];
          break;
        case -1:
          palettes = palettes.slice(0, -1);
          break;
      }
    } else showModal = true;
  };
</script>
  • 第四十六行:const handleClick = (e) => {
      落落長一串程式碼,只需要修改 handleClick 當中的邏輯。

  • 第四十九行:if (0 <= tobeCount && tobeCount < 7) {
      讓 tobeCount 允許為 0,這樣我們才有機會把 palettes 陣列當中的所有項目清空,展現出 {:else} 的功能。

  修改好 App.svelte 之後,先來試試看如果沒有加上 {:else} 會發生什麼事。當我們從計數器不斷移除色票之後,最後色票欄就變得像圖一空空如也的樣子,什麼都沒有顯示了。

https://i.ibb.co/KNvJptj/18.gif
圖一、空空如也的狀態

  如果不喜歡這樣的效果,讓我們練習練習今天學會的語法,試著加上 {:else} 來處理空陣列的狀況吧:

/src/lib/Palettes.svelte
<script>
  import unlock from "../assets/unlock.svg";
  export let palettes;
</script>

<div class="palettes">
  {#each palettes as { hex, id } (id)}
    <div class="card">
      <div class="palette" style="background: #{hex}" />
      <div class="hex-code">
        <p>
          {hex}
        </p>
      </div>
      <div class="lock-icon">
        <img src={unlock} alt="color-unlocked" />
      </div>
    </div>
  {:else}
    <div class="card no-color">
      <div>
        <p>No color to show. Please add a color.</p>
      </div>
    </div>
  {/each}
</div>
  • 第十九行:{:else}
      在 {#each} 之後加上 {:else},表示我們想要用以下的邏輯段落來處理 palettes 為空陣列的情況。

  • 第二十行:<div class="card no-color">
      放入一個 HTML 的 <div>,並加上 cardno-color 這兩個 class 來修飾這個 <div>

  • 第二十五行:{/each}
      不需要做修改,只是提醒大家記得要用 {/each} 來結束整個 each 邏輯段落。

https://i.ibb.co/7jvm44w/18.gif
圖二、請新增一個顏色

  太棒了,我們學會如何在 each 邏輯段落中用 {:else} 來處理空陣列囉!完整的程式碼可以在 Github 資源庫上面找到。好的,那麼今天的文章內容就到這邊了,謝謝大家。


上一篇
第 17 天:Svelte 中的邏輯運作:`each` 邏輯區塊(二)
下一篇
第 19 天:Svelte 中的邏輯運作:`if` 邏輯區塊
系列文
了不起的 Svelte30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言