Svelte 基本模板語法
tags: Svelte
category: Front-End
description: Svelte 基本模板語法
created_at: 2023/04/01 16:00:00

前言
老樣子,假設你已經做好開新專案與環境設定裡面所做的事
這邊對 Vue 或 React 的使用者可能會覺得比較跳一些(?),雖然可能也還好,看過那麼多東西見怪不怪了,看淡就好。
在 Vue 當中模板語法比較像是指令,寫在 HTML tag 上面
在 React 當中就都是 JavaScript 隨你組
而在 Svelte 會比較像是後端的模板引擎(Template Engine)
本篇會介紹到以下內容
- 插入變數
- 插入 html
- 屬性綁定
- 定義 style
- 邏輯相關
- if 相關
- 迴圈相關
先從最簡單的開始 - 插入變數
在 Vue 當中是使用兩個大括號,而這邊會比較像 React,是使用一對大括號包住。
<script>
let count = 100;
</script>
<div>count is: {count}</div>
包住的也不一定要是變數,主要是 javascript expression
<div>count is: {100 * 2}</div>
插入 html
一般來說基本的大括號包住在任何框架都會有做一些處理,不會真的去 render 出 html(安全性考量),但也會提供方法去讓你直接輸出 html,在必要的時候可以使用。
<script>
let html = `
<div>count is: {100 * 2}</div>
`;
</script>
{html}
你會發現畫面上呈現出 <div>count is: {100 * 2}</div>,而不是預期中的結果。
要輸出 html 的話,要改成下面這樣
<script>
let htmlString = `
<div>count is: {100 * 2}</div>
`;
</script>
{@html htmlString}
但這時你會發現兩個問題
- 我的
VSCode報錯,{@html} can lead to XSS attack.這代表你的eslint很乖- 只是建議你不要這樣寫,當然你也可以去關設定讓他不要跳這個提醒
- 畫面上顯示
count is: {100 * 2}而不是count is: 200- 這是因為
svelte在你使用html輸出的時候,不會幫你做任何處理,就直接輸出
- 這是因為
總之盡量不要這樣寫,除非你很清楚你在幹嘛。
屬性綁定
屬性綁定的部分就跟 React 比較像了,在 Vue 是使用 :屬性="",來綁定,例如
<div :class="classes" />
而在 Svelte 則是比較像 React,如下:
<script>
let classes = 'bg-blue-500 text-white';
</script>
<div class={classes}>Hi</div>
而 Svelte 還有提供一個語法糖,如果你的變數剛好跟屬性名稱一樣,可以簡寫,如下
<script>
let src = 'https://picsum.photos/200/300';
let alt = 'Image';
</script>
<img {src} {alt} />
定義 style
在 Svelte 的單個檔案中也可以定義 style ,這點跟 Vue 比較像,而且他的 style 都是 scope 的,不會去汙染到其他的元件,會比較像 Vue 的 <style scoped></style>
雖然還沒講到組件,不過就先照貼吧(?)
建立檔案: /src/components/Child.svelte
<div>Child</div>
<style>
div {
color: blue;
}
</style>
然後在你的 /src/routes/+page.svelte 貼上:
<script>
import Child from '../components/Child.svelte';
</script>
<div>Root</div>
<Child />
<style>
div {
color: red;
}
</style>
然後你會看到畫面中兩個 div 的顏色不一樣。
if 相關語法
進到 if 相關的語法了,這邊跟誰都不像,只跟模板引擎像
- 在
Vue中,可以簡單透過v-if達到 - 在
React中,通常透過()?():()或是() && ()之類的JavaScript表達式達到
直接看範例
<script>
let count = 5;
</script>
{#if count > 0}
<p>Count is {count}</p>
{/if}
這邊當 count > 0 才會顯示內容,可以為他加入 else,變成以下
<script>
let count = 0;
</script>
{#if count > 0}
<p>Count is {count}</p>
{:else}
<p>Count is zero</p>
{/if}
當然也有 else if 可以用
<script>
let age = 18;
</script>
{#if age < 18}
<p>Sorry, you're too young to enter this site.</p>
{:else if age < 65}
<p>Welcome to the site!</p>
{:else}
<p>Sorry, you're too old to enter this site.</p>
{/if}
這一段內容是 Copilot 幫我生成的
迴圈相關
老樣子,跟誰都不像,所以直接看範例
<script>
let products = [
{
id: 1,
name: 'Product 1',
price: 100
},
{
id: 2,
name: 'Product 2',
price: 200
},
{
id: 3,
name: 'Product 3',
price: 300
}
];
</script>
{#each products as product}
<div>
{product.name}: {product.price}
</div>
{/each}
應該會看到畫面上呈現
Product 1: 100
Product 2: 200
Product 3: 300
也可以在迴圈的時候拿到 index
{#each products as product, i}
<div>
index={i}, {product.name}: {product.price}
</div>
{/each}
會看到以下
index=0, Product 1: 100
index=1, Product 2: 200
index=2, Product 3: 300
你也可以解構他,少打一點字:
{#each products as { name, price }}
<div>
{name}: {price}
</div>
{/each}
重要的 key 呢?,當然也有
{#each products as { id, name, price } (id)}
<div>
{name}: {price}
</div>
{/each}
那個小括號包起來的就是 key 帶的值
至於不帶 key 會怎樣?,去看Vue3 - 基本的模板語法的最下面,有講到如果不帶 key 會怎樣,還有範例。
而在 Svelte 你不帶,也會發生一樣的事情,總之引用那篇的結論: 講了這麼多,如果不想理解那麼多,總之你就乖乖設 key 為唯一值就對了。
最後統整一下 for 的語法,大概會長這樣
{#each 可迭代物件 as 每一個元素, 索引 (key值)}
<!-- ... -->
{/each}
希望這樣能更幫助理解,總之就是 , 隔開和 空白 隔開: 每一個元素, 索引 (key),按自己需求去寫。
總結
在寫 Svelte 的時候是假設看的人都有其他前端開發經驗了,所以有些地方會跳比較快,而會覺得比較不習慣的可能會是模板的部分(如果沒有寫過任何模板引擎的話),不過反正 IDE 有插件可以幫你寫,或是 Copilot 會幫你補 (?),所以現在應該也不是什麼大問題了。