iT邦幫忙

2023 iThome 鐵人賽

DAY 7
0
Modern Web

了不起的 Svelte系列 第 7

第 07 天:Svelte 中的 Javascript:賦值

  • 分享至 

  • xImage
  •  

第 07 天:Svelte 中的 Javascript:賦值

凱瑟琳彎過身來悄聲對我說:「我的專案狀態 (state) 跟文件物件模型 (DOM) 總是沒辦法同步。」
「他們沒辦法同步嗎?」
她的眼神先是看向莫爾朵,接著轉向湯姆:「一點辦法也沒有。」

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

第 07 天要講的事

  1. Svelte 中的 Javascript:賦值

  系列文介紹到這邊,我們已經差不多認識了 Svelte 專案的檔案架構,Svelte 元件當中 HTML 跟 CSS 的用法,今天要開始來介紹 Svelte 當中的 Javascript,是如何被重新詮釋的既強大又平易近人。
  總的來說,互動式使用者介面 (reactive user interface) 設計的概念,是以 Javascript 記錄下介面的狀態,當狀態改變時,介面呈現的內容跟著改變,藉此達到互動的效果。
  而我們已經知道如何在 Svelte 元件當中,用大括弧 {} 將 Javascript 的狀態寫入 HTML 元素裡面了 (見第 05 天)。剩下的就是如何改變 Javascript 的狀態,以及如何讓 HTML 隨著 Javascript 狀態的改變而進行更新。

Svelte 中的 Javascript:賦值

  若是從純純的 Javascript (Vanilla Javascript) 出發,改變 Javascript 的狀態跟更新 HTML 的元素是兩件事,所以會看到兩行程式碼:

let someState = updatedState;
document.querySelector('someSelector').innerText = someState;

  在 Svelte 當中,則是透過編譯器 (compiler) 來自動處理這些工作,專案開發者只要簡簡單單的寫下一行程式碼就行。哪一行呢?就是這一行:

let someState = updatedState;

  也就是說,只要在 Javascript 透過賦值 (assignment) 這個動作,Svelte 的編譯器就會自動編譯出可以隨著賦值而進行更新的 HTML 元素了。這也太神奇了吧,趕快讓我們來試試吧。我們來修改 Counter.svelte 這個元件,讓元件當中呈現的數字隨著時間而更新看看:

/src/lib/Counter.svelte
<script>
  let count = 0;
  const countArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
  countArray.forEach(x => {
    setTimeout(() => count = x, x * 1000);
  });
</script>

<section>
  <h1>Create Color Palette for Me!</h1>

  <div class='counter'>
    <button>
      <svg aria-hidden="true" viewBox="0 0 1 1">
        <path d="M0,0.5 L1,0.5" />
      </svg>
    </button>
    <div class="counter-viewer">
      <p>{count}</p>
    </div>
    <button>
      <svg aria-hidden="true" viewBox="0 0 1 1">
        <path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" />
      </svg>
    </button>
  </div>
</section>
  • 第一行:<script>
      建立一個 Javascript 運作的段落。

  • 第二行:let count = 0;
      宣告一個變數 count

  • 第三行:const countArray = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
      宣告一個陣列變數 countArray,當中放進我們想讓 count 隨著時間而更新的值。

  • 第五行:setTimeout(() => count = x, x * 1000);
      設定好我們的計時器,讓 count 隨著時間而更新成不同的值。

  • 第十九行:<p>{count}</p>
      接著在 HTML 元素當中使用這個變數 count

  然後就沒有然後了。來看看我們的成果吧:

https://i.ibb.co/vBC2pp5/Vite-Svelte-Profile-1-Microsoft-Edge-2023-09-22-07-04-46.gif
圖一、1、2、3、4、5、6、7、8、9、10!

  什麼,這麼神奇,居然只要這樣就行!沒錯,所有的辛苦工作編譯器都幫我們完成了。
  由於編譯器可以偵測 Javascript 的變數被使用在哪些地方,同時 Svelte 也重新定義了 let 以及 =,所以開發者們只要利用賦值 (assignment, =) 來更新 Javascript 的變數,Svelte 的編譯器就會自動找出需要跟著更新的地方,並且打造出能夠隨著 Javascript 變數而更新的使用者介面。
  最後要提醒一下,因為 Svelte 是藉由賦值 (assign, =) 這個動作來偵測變數的改變,在這以外,如果變數有任何改變,Svelte 可是沒辦法處理的。舉例來說,Javascript 陣列的函式,有些是會原地 (in-place) 改變陣列的資料內容的。當我們在 Svelte 當中用這種函式來改變變數,並不會觸發使用者介面的更新,因此就沒辦法即時將 Javascript 的狀態回饋到使用者介面上了。
  那應該怎麼做呢?舉例來說:

let numArray = [0, 9, 2, 2];
numArray.sort()
// 這時 numArray 就會變成 [0, 2, 2, 9],但 Svelte 會渾然不覺

  因為我們並不是透過賦值來更動 numArray 這個變數,所以 Svelte 會渾然不覺這個變數已經不同了。那怎麼辦呢?這個時候只要加一個動作來觸發 Svelte 偵測變數改變就行了:

let numArray = [0, 9, 2, 2];
numArray.sort()
// 這時 numArray 就會變成 [0, 2, 2, 9],但 Svelte 會渾然不覺

numArray = numArray
// 沒錯就是這麼簡單

  沒錯,就是把變數重新賦值一次就行。所以原則很簡單,只要看到 =,Svelte 就能夠幫我們追蹤變數!那麼今天的內容就到這邊了,謝謝各位讀者。


上一篇
第 06 天:Svelte 中的 CSS
下一篇
第 08 天:Svelte 中的 Javascript:宣告
系列文
了不起的 Svelte30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言