Template Syntax 模板語法感覺有魔法的感覺~
希望跟我想像的一樣好用簡單~
Vue 使用基於 HTML 的模板語法,讓你可以聲明式地將渲染的 DOM 綁定到底層組件實例的數據上。所有的 Vue 模板都是語法上有效的 HTML,可以被符合標準的瀏覽器和 HTML 解析器解析。
在底層,Vue 將模板編譯成高度優化的 JavaScript 代碼。結合響應式系統,Vue 能夠智能地判斷需要重新渲染的最小組件數量,並在應用狀態變化時應用最少的 DOM 操作。如果你熟悉虛擬 DOM
的概念並且喜歡直接使用 JavaScript 的原始能力,你也可以直接寫渲染函數而不是模板,並可選擇使用 JSX
。需要注意的是,這些渲染函數不會享受與模板相同級別的編譯時優化
。虛擬 DOM 是現代 Web 開發中的一個重要概念,它能幫助開發者構建高效、動態的用戶界面,並提高應用的性能。
最基本的數據綁定形式是使用「Mustache
」語法(雙花括號)進行文本插值:
<span>Message: {{ msg }}</span>
Mustache 標籤會被對應組件實例中的 msg
屬性的值所取代。當 msg
屬性改變時,這個值也會被自動更新。
在 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
,且切勿在用戶提供的內容上使用。
Mustaches 不能在 HTML 屬性內部使用。可以使用 v-bind
指令取代:
<div v-bind:id="dynamicId"></div>
v-bind
指令告訴 Vue 讓元素的 id
屬性與組件的 dynamicId
屬性保持同步。如果綁定的值為 null
或 undefined
,那麼該屬性將會從渲染的元素中移除。
由於 使用頻繁v-bind
,它有一個專門的簡寫語法:
<div :id="dynamicId"></div>
以 :
開頭的屬性看起來可能與普通 HTML 有些不同,但實際上這是一個有效的屬性名稱字符,所有支持 Vue 的瀏覽器都能正確解析。並且,它們不會出現在最終渲染的標記中。簡寫語法是可選的,但當你學習更多用法時,你會欣賞到它的便利。
接下來文件中,將在代碼示例中使用簡寫語法,因為這是 Vue 開發者最常見使用方式。
僅支持於 3.4+ 版本
如果屬性名稱與綁定的 JavaScript 值相同,語法可以進一步簡化,省略屬性值:
<!-- 與 :id="id" 相同 -->
<div :id></div>
<!-- 這也有效 -->
<div v-bind:id></div>
布林屬性是可以通過其在元素上的存在來表示 true
/ false
值的屬性。例如,disabled
是最常用的布林屬性之一。
在這種情況下,v-bind
的工作方式有點不同:
<button :disabled="isButtonDisabled">Button</button>
如果 isButtonDisabled
的值為 true
,則 disabled
屬性將會包含在內。如果值為空字符串,屬性也會被包含,保持與 <button disabled="">
一致。對於其他 falsy
值(false, null, undefined),該屬性將會被省略。
如果你有一個表示多個屬性的 JavaScript 對象,如下所示:
const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
你可以通過使用 v-bind
而不帶參數來綁定它們到單個元素:
<div v-bind="objectOfAttrs"></div>
到目前為止,我們只在模板中綁定了簡單的屬性鍵。但實際上,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 表達式:
每個綁定只能包含一個表達式。表達式是一段可以評估為值的代碼。簡單的檢查方法是看它是否可以在 return
之後使用。因此,以下是不會工作的:
<!-- 這是一個語句statement,不是一個表達式expression: -->
{{ var a = 1 }}
<!-- 流控制也不起作用,使用三元表達式 -->
{{ if (ok) { return message } }}
可以在綁定表達式中調用組件暴露的方法:
<time :title="toTitleDate(date)" :datetime="date">
{{ formatDate(date) }}
</time>
提示:綁定表達式中的函數將在組件每次更新時調用,因此它們不應該有任何副作用,如更改數據或觸發異步操作。
模板表達式是被沙盒化的,僅能訪問限制列表中的全局變量。這個列表包括常用的內置全局變量,如 Math
和 Date
。
不在列表中的全局變量(例如附加到 window
上的用戶屬性)在模板表達式中將不可訪問。但是,你可以通過將它們添加到 app.config.globalProperties
中來明確定義所有 Vue 表達式的額外全局變量。
指令是具有 v-
前綴的特殊屬性。Vue 提供了許多內置指令,包括之前介紹的 v-html
和 v-bind
。
指令屬性的值預期為單個 JavaScript 表達式(除了 v-for
、v-on
和 v-slot
,這些會在後面的部分討論)。指令的作用是當其表達式的值發生變化時,反應性地更新 DOM。以 v-if
為例:
<p v-if="seen">Now you see me</p>
在這裡,v-if
指令將根據 seen
表達式的真值來移除或插入 <p>
元素。
一些指令可以接受一個「參數」,用冒號表示在指令名稱之後。例如,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>
這裡,參數是要監聽的事件名稱:click
。v-on
有一個相應的簡寫,即 @
字符。我們將在稍後更詳細地討論事件處理。
也可以在指令參數中使用 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
。
動態參數預期評估為字符串,除了 null
。特殊值 null
可用於顯式刪除綁定。任何其他非字符串值都會觸發警告。
動態參數表達式有一些語法限制,因為某些字符(如空格和引號)在 HTML 屬性名稱中是無效的。例如,以下是無效的:
<!-- 這將觸發編譯器警告。 -->
<a :['foo' + bar]="value"> ... </a>
如果需要傳遞一個複雜的動態參數,最好使用計算屬性,我們將在稍後介紹。
使用 DOM 模板時(直接在 HTML 文件中寫入的模板),應避免使用大寫字母命名鍵,因為瀏覽器會將屬性名稱轉換為小寫:
<a :[someAttr]="value"> ... </a>
上述內容將在 DOM 模板中轉換為 :[someattr]
。如果你的組件有一個 someAttr
屬性而不是 someattr
,你的代碼將不起作用。單文件組件內的模板不受此限制。
修飾符是以點號表示的特殊後綴,表示指令應以某種特殊方式綁定。例如,.prevent
修飾符告訴 v-on
指令在觸發的事件上調用 event.preventDefault()
:
<form @submit.prevent="onSubmit">...</form>
你將在稍後的 v-on
和 v-model
特性介紹中看到其他修飾符的例子。
最終指令語法的可視化示例
講了這麼多,還是沒有什麼特別的感覺?
這些東西實務上怎麼設定?