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
會幫你補 (?),所以現在應該也不是什麼大問題了。