2024-09-11|閱讀時間 ‧ 約 23 分鐘

EP3 - 模板語法

Template Syntax 模板語法感覺有魔法的感覺~
希望跟我想像的一樣好用簡單~

Vue 使用基於 HTML 的模板語法,讓你可以聲明式地將渲染的 DOM 綁定到底層組件實例的數據上。所有的 Vue 模板都是語法上有效的 HTML,可以被符合標準的瀏覽器和 HTML 解析器解析。

在底層,Vue 將模板編譯成高度優化的 JavaScript 代碼。結合響應式系統,Vue 能夠智能地判斷需要重新渲染的最小組件數量,並在應用狀態變化時應用最少的 DOM 操作。

如果你熟悉虛擬 DOM 的概念並且喜歡直接使用 JavaScript 的原始能力,你也可以直接寫渲染函數而不是模板,並可選擇使用 JSX。需要注意的是,這些渲染函數不會享受與模板相同級別的編譯時優化

什麼是虛擬 DOM?

  1. 虛擬 DOM 的定義
    • 虛擬 DOM 是一個抽象的 JavaScript 對象,代表了實際 DOM 結構的輕量級副本。它在記憶體中進行操作,而不是直接修改瀏覽器的實際 DOM。
  2. 工作原理
    • 當應用的狀態改變時,Vue 或其他使用虛擬 DOM 的框架會更新虛擬 DOM。
    • 框架會比較虛擬 DOM 與先前的虛擬 DOM 樹的差異,這個過程稱為 "diffing"。
    • 根據這些差異,框架會計算出最小的 DOM 更新操作,然後只進行這些必要的操作來更新實際 DOM。

虛擬 DOM 是現代 Web 開發中的一個重要概念,它能幫助開發者構建高效、動態的用戶界面,並提高應用的性能。

文本插值 - Text Interpolation

最基本的數據綁定形式是使用「Mustache」語法(雙花括號)進行文本插值:

<span>Message: {{ msg }}</span>

Mustache 標籤會被對應組件實例中的 msg 屬性的值所取代。當 msg 屬性改變時,這個值也會被自動更新。

原始HTML - Raw HTML

在 Vue 中,雙大括號 {{ }} 用於文本插值,這會將數據作為純文本輸出,而不是 HTML。如果要輸出真正的 HTML,您需要使用 v-html 指令。

<!-- 使用文本插值 -->
<p>Using text interpolation: {{ rawHtml }}</p>

<!-- 使用 v-html 指令 -->
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

在這裡我們遇到了一些新東西。你看到的 v-html 屬性稱為指令(directive)。指令以 v- 為前綴,以表示它們是 Vue 提供的特殊屬性,正如你可能猜到的,它們對渲染的 DOM 應用特殊的響應式行為。在這裡,基本上是在說「保持這個元素的內部 HTML 與當前活動實例的 rawHtml 屬性同步。」

span 元素的內容將被替換為 rawHtml 屬性的值,這些值會被解釋為普通的 HTML——數據綁定會被忽略。請注意,你不能使用 v-html 來組合模板片段,因為 Vue 不是基於字串的模板引擎。相反,組件被視為 UI 重用和組合的基本單位。

安全警告⮕ 在你的網站上動態渲染任意 HTML 可能非常危險,因為這可能會導致 XSS(跨站腳本攻擊)漏洞。僅在可信內容上使用 v-html,且切勿在用戶提供的內容上使用。

屬性綁定 - Attribute Bindings

Mustaches 不能在 HTML 屬性內部使用。可以使用 v-bind 指令取代:

<div v-bind:id="dynamicId"></div>

v-bind 指令告訴 Vue 讓元素的 id 屬性與組件的 dynamicId 屬性保持同步。如果綁定的值為 nullundefined,那麼該屬性將會從渲染的元素中移除。

簡寫(Shorthand)

由於 使用頻繁v-bind ,它有一個專門的簡寫語法:

<div :id="dynamicId"></div>

: 開頭的屬性看起來可能與普通 HTML 有些不同,但實際上這是一個有效的屬性名稱字符,所有支持 Vue 的瀏覽器都能正確解析。並且,它們不會出現在最終渲染的標記中。簡寫語法是可選的,但當你學習更多用法時,你會欣賞到它的便利。

接下來文件中,將在代碼示例中使用簡寫語法,因為這是 Vue 開發者最常見使用方式。

同名簡寫(Same-name Shorthand)

僅支持於 3.4+ 版本
如果屬性名稱與綁定的 JavaScript 值相同,語法可以進一步簡化,省略屬性值:

<!--:id="id" 相同 -->
<div :id></div>

<!-- 這也有效 -->
<div v-bind:id></div>

布林屬性(Boolean Attributes)

布林屬性是可以通過其在元素上的存在來表示 true / false 值的屬性。例如,disabled 是最常用的布林屬性之一。

在這種情況下,v-bind 的工作方式有點不同:

<button :disabled="isButtonDisabled">Button</button>

如果 isButtonDisabled 的值為 true,則 disabled 屬性將會包含在內。如果值為空字符串,屬性也會被包含,保持與 <button disabled=""> 一致。對於其他 falsy 值(false, null, undefined),該屬性將會被省略。

動態綁定多個屬性(Dynamically Binding Multiple Attributes)

如果你有一個表示多個屬性的 JavaScript 對象,如下所示:

const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}

你可以通過使用 v-bind 而不帶參數來綁定它們到單個元素:

<div v-bind="objectOfAttrs"></div>

使用 JavaScript 表達式 - Using JavaScript Expressions

到目前為止,我們只在模板中綁定了簡單的屬性鍵。但實際上,Vue 支持在所有數據綁定中使用完整的 JavaScript 表達式。

此表達式將計算 number 屬性加 1 的值。

{{ number + 1 }}

此表達式將根據 ok 的值來顯示 'YES' 或 'NO'。

{{ ok ? 'YES' : 'NO' }}

此表達式將 message 字符串反轉後顯示。

{{ message.split('').reverse().join('') }}

此表達式將生成 id 屬性的值,如 list-1

<div :id="`list-${id}`"></div>

這些表達式將在當前組件實例的數據範圍內作為 JavaScript 評估。
在 Vue 模板中,可以在以下位置使用 JavaScript 表達式:

  • 文本插值 (使用雙大括號)
  • 任何 Vue 指令的屬性值 (以 v- 開頭的特殊屬性)

只能使用表達式 - Expressions Only

每個綁定只能包含一個表達式。表達式是一段可以評估為值的代碼。簡單的檢查方法是看它是否可以在 return 之後使用。因此,以下是不會工作的:

<!-- 這是一個語句statement,不是一個表達式expression: -->
{{ var a = 1 }}

<!-- 流控制也不起作用,使用三元表達式 -->
{{ if (ok) { return message } }}

調用函數 - Calling Functions

可以在綁定表達式中調用組件暴露的方法:

<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>

提示:綁定表達式中的函數將在組件每次更新時調用,因此它們不應該有任何副作用,如更改數據或觸發異步操作。

限制全局訪問 - Restricted Globals Access

模板表達式是被沙盒化的,僅能訪問限制列表中的全局變量。這個列表包括常用的內置全局變量,如 MathDate

不在列表中的全局變量(例如附加到 window 上的用戶屬性)在模板表達式中將不可訪問。但是,你可以通過將它們添加到 app.config.globalProperties 中來明確定義所有 Vue 表達式的額外全局變量。

指令 - Directives

指令是具有 v- 前綴的特殊屬性。Vue 提供了許多內置指令,包括之前介紹的 v-htmlv-bind

指令屬性的值預期為單個 JavaScript 表達式(除了 v-forv-onv-slot,這些會在後面的部分討論)。指令的作用是當其表達式的值發生變化時,反應性地更新 DOM。以 v-if 為例:

<p v-if="seen">Now you see me</p>

在這裡,v-if 指令將根據 seen 表達式的真值來移除或插入 <p> 元素。

參數 - Arguments

一些指令可以接受一個「參數」,用冒號表示在指令名稱之後。例如,v-bind 指令用於反應性地更新 HTML 屬性:

<a v-bind:href="url"> ... </a>

<!-- 簡寫 -->
<a :href="url"> ... </a>

這裡,href 是參數,它告訴 v-bind 指令將元素的 href 屬性綁定到 url 表達式的值。在簡寫中,參數之前的所有內容(即 v-bind:)都被濃縮成一個字符 :

另一個例子是 v-on 指令,用於監聽 DOM 事件:

<a v-on:click="doSomething"> ... </a>

<!-- 簡寫 -->
<a @click="doSomething"> ... </a>

這裡,參數是要監聽的事件名稱:clickv-on 有一個相應的簡寫,即 @ 字符。我們將在稍後更詳細地討論事件處理。

動態參數 - Dynamic Arguments

也可以在指令參數中使用 JavaScript 表達式,方法是將其用方括號括起來:

<!-- 注意參數表達式有一些限制,如下文所述。 -->
<a v-bind:[attributeName]="url"> ... </a>

<!-- 簡寫 -->
<a :[attributeName]="url"> ... </a>

在這裡,attributeName 將作為 JavaScript 表達式動態計算,其計算值將作為參數的最終值。例如,如果你的組件實例有一個名為 attributeName 的數據屬性,其值為 "href",那麼此綁定將等同於 v-bind:href

同樣,你可以使用動態參數來綁定一個處理程序到動態事件名稱:

<a v-on:[eventName]="doSomething"> ... </a>

<!-- 簡寫 -->
<a @[eventName]="doSomething"> ... </a>

在這個例子中,當 eventName 的值為 "focus" 時,v-on:[eventName] 將等同於 v-on:focus

動態參數值的約束 - Dynamic Argument Value Constraints

動態參數預期評估為字符串,除了 null。特殊值 null 可用於顯式刪除綁定。任何其他非字符串值都會觸發警告。

動態參數語法限制 - Dynamic Argument Syntax Constraints

動態參數表達式有一些語法限制,因為某些字符(如空格和引號)在 HTML 屬性名稱中是無效的。例如,以下是無效的:

<!-- 這將觸發編譯器警告。 -->
<a :['foo' + bar]="value"> ... </a>

如果需要傳遞一個複雜的動態參數,最好使用計算屬性,我們將在稍後介紹。

使用 DOM 模板時(直接在 HTML 文件中寫入的模板),應避免使用大寫字母命名鍵,因為瀏覽器會將屬性名稱轉換為小寫:

<a :[someAttr]="value"> ... </a>

上述內容將在 DOM 模板中轉換為 :[someattr]。如果你的組件有一個 someAttr 屬性而不是 someattr,你的代碼將不起作用。單文件組件內的模板不受此限制。

修飾符 - Modifiers

修飾符是以點號表示的特殊後綴,表示指令應以某種特殊方式綁定。例如,.prevent 修飾符告訴 v-on 指令在觸發的事件上調用 event.preventDefault()

<form @submit.prevent="onSubmit">...</form>

你將在稍後的 v-onv-model 特性介紹中看到其他修飾符的例子。

最終指令語法的可視化示例

講了這麼多,還是沒有什麼特別的感覺?
這些東西實務上怎麼設定?



分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.