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
特性介紹中看到其他修飾符的例子。
最終指令語法的可視化示例
講了這麼多,還是沒有什麼特別的感覺?
這些東西實務上怎麼設定?