跳轉到內容

模板語法

Vue 使用基於 HTML 的模板語法,允許您宣告性地將渲染的 DOM 繫結到底層元件例項的資料。所有 Vue 模板都是語法有效的 HTML,可以被遵循規範的瀏覽器和 HTML 解析器解析。

在底層,Vue 將模板編譯成高度最佳化的 JavaScript 程式碼。結合響應性系統,Vue 可以智慧地確定需要重新渲染的最小元件數量,並在應用狀態變化時執行最小的 DOM 操作。

如果您熟悉虛擬 DOM 概念並喜歡 JavaScript 的原始力量,您也可以直接 編寫渲染函式 而不是模板,並提供可選的 JSX 支援。但請注意,它們不像模板那樣享受相同的編譯時最佳化級別。

文字插值

資料繫結最基本的形式是使用“Mustache”語法(雙大括號)進行文字插值

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

大括號標籤將被替換為對應元件例項 的 msg 屬性值。它也會在 msg 屬性變化時更新。

原始 HTML

雙大括號將資料解釋為純文字,而不是 HTML。為了輸出真正的 HTML,您需要使用 v-html 指令

template
<p>Using text interpolation: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

使用文字插值: <span style="color: red">This should be red.</span>

使用 v-html 指令: This should be red.

在這裡我們遇到了一些新事物。您看到的 v-html 屬性被稱為一個 指令。指令以 v- 字首開頭,以表示它們是由 Vue 提供的特殊屬性,正如您可能猜測的,它們會給渲染的 DOM 應用特殊的響應式行為。在這裡,我們基本上是說“保持這個元素的內部 HTML 與當前活動例項上的 rawHtml 屬性保持一致。”

span 的內容將被 rawHtml 屬性的值替換,該值被解釋為純 HTML - 忽略資料繫結。請注意,您不能使用 v-html 來組合模板部分,因為 Vue 不是一個基於字串的模板引擎。相反,元件是 UI 重用和組合的基本單元。

安全警告

在您的網站上動態渲染任意 HTML 可能非常危險,因為它很容易導致 XSS 漏洞。僅在有信任的內容時使用 v-html絕對不要 在使用者提供的內用使用。

屬性繫結

不能在 HTML 屬性中使用花括號。相反,使用一個 v-bind 指令

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

v-bind 指令指示 Vue 保持元素的 id 屬性與元件的 dynamicId 屬性同步。如果繫結值為 nullundefined,則該屬性將從渲染的元素中刪除。

簡寫

因為 v-bind 非常常用,所以它有一個專門的簡寫語法

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

: 開頭的屬性可能看起來與正常 HTML 有點不同,但實際上它是屬性名中的一個有效字元,並且所有 Vue 支援的瀏覽器都可以正確解析它。此外,它們不會出現在最終的渲染標記中。簡寫語法是可選的,但您在以後學習其用法時可能會發現它很有用。

在本指南的其餘部分,我們將使用簡寫語法在程式碼示例中,因為這是 Vue 開發者最常用的用法。

同名欄位簡寫

  • 僅在 3.4+ 版本中支援

如果屬性名與正在繫結的 JavaScript 值同名,則語法可以進一步簡化,以省略屬性值

template
<!-- same as :id="id" -->
<div :id></div>

<!-- this also works -->
<div v-bind:id></div>

這與在 JavaScript 中宣告物件時使用的屬性簡寫語法類似。請注意,這是一個僅在 Vue 3.4 及以上版本中可用的功能。

布林屬性

布林屬性 是透過在元素上出現來表示真 / 假值的屬性。例如,disabled 是最常用的布林屬性之一。

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

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

如果 isButtonDisabled 有一個 真值,則將包含 disabled 屬性。如果值是空字串,它也將包含,以保持與 <button disabled=""> 的一致性。對於其他 假值,將省略屬性。

動態繫結多個屬性

如果您有一個表示多個屬性的 JavaScript 物件,看起來像這樣

js
const objectOfAttrs = {
  id: 'container',
  class: 'wrapper',
  style: 'background-color:green'
}
js
data() {
  return {
    objectOfAttrs: {
      id: 'container',
      class: 'wrapper'
    }
  }
}

您可以使用不帶引數的 v-bind 將它們繫結到單個元素上

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

使用JavaScript表示式

到目前為止,我們只在我們的模板中繫結到簡單的屬性鍵。但實際上,Vue支援所有資料繫結中JavaScript表示式的全部功能

template
{{ number + 1 }}

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

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

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

這些表示式將在當前元件例項的資料作用域中作為JavaScript進行評估。

在Vue模板中,JavaScript表示式可以在以下位置使用

  • 在文字插值(花括號)內
  • 在任何Vue指令的屬性值中(以v-開頭的特殊屬性)

僅表示式

每個繫結只能包含一個單一的表示式。一個表示式是一段可以被評估為值的程式碼。一個簡單的檢查是看它是否可以在return之後使用。

因此,以下將不會工作

template
<!-- this is a statement, not an expression: -->
{{ var a = 1 }}

<!-- flow control won't work either, use ternary expressions -->
{{ if (ok) { return message } }}

呼叫函式

在繫結表示式中呼叫元件暴露的方法是可能的

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

提示

在繫結表示式中呼叫的函式會在元件更新時被呼叫,因此它們不應該有任何副作用,比如改變資料或觸發非同步操作。

限制全域性訪問

模板表示式是沙箱化的,並且只有訪問一個限制的全域性變數列表。該列表公開了常用內建全域性變數,如MathDate

不在列表中明確包含的全域性變數,例如window上的使用者附加屬性,在模板表示式中將不可訪問。但是,您可以顯式地為所有Vue表示式定義額外的全域性變數,方法是將它們新增到app.config.globalProperties

指令

指令是具有v-字首的特殊屬性。Vue提供了一些內建指令,包括我們上面介紹的v-htmlv-bind

指令屬性值應期望是單個JavaScript表示式(除了v-forv-onv-slot,這些將在後面的相應部分中討論)。指令的職責是在其表示式的值更改時,有反應性地更新DOM。以v-if為例

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

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

引數

一些指令可以接受一個“引數”,由指令名稱後的冒號表示。例如,v-bind指令用於有反應性地更新HTML屬性

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

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

在這裡,href 是引數,它告訴 v-bind 指令將元素的 href 屬性繫結到表示式 url 的值。在簡寫形式中,引數之前的內容(即 v-bind:)被壓縮成一個字元 :

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

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

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

在這裡,引數是要監聽的事件名稱:clickv-on 有一個對應的簡寫形式,即 @ 字元。我們還將更詳細地討論事件處理。

動態引數

透過使用方括號包圍,也可以在指令引數中使用 JavaScript 表示式

template
<!--
Note that there are some constraints to the argument expression,
as explained in the "Dynamic Argument Value Constraints" and "Dynamic Argument Syntax Constraints" sections below.
-->
<a v-bind:[attributeName]="url"> ... </a>

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

在這裡,attributeName 將作為一個 JavaScript 表示式動態求值,其求值後的結果將作為引數的最終值。例如,如果你的元件例項有一個數據屬性,名為 attributeName,其值為 "href",那麼這個繫結將等同於 v-bind:href

同樣,你可以使用動態引數來將處理程式繫結到動態事件名稱

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

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

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

動態引數值約束

動態引數預期求值為一個字串,除了 null 之外。特殊值 null 可以用來顯式移除繫結。任何其他非字串值都會觸發警告。

動態引數語法約束

由於某些字元(如空格和引號)在 HTML 屬性名稱中是無效的,因此動態引數表示式有一些語法約束。例如,以下是不合法的

template
<!-- This will trigger a compiler warning. -->
<a :['foo' + bar]="value"> ... </a>

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

當使用 in-DOM 模板(直接在 HTML 檔案中編寫的模板)時,還應避免使用大寫字母命名鍵,因為瀏覽器會將屬性名稱轉換為小寫

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

上述內容在 in-DOM 模板中將被轉換為 :[someattr]。如果你的元件有 someAttr 屬性而不是 someattr,則你的程式碼將無法正常工作。單檔案元件中的模板 受此約束。

修飾符

修飾符是特殊的字尾,由點表示,它表示指令應以某種特殊方式繫結。例如,.prevent 修飾符告訴 v-on 指令在觸發的事件上呼叫 event.preventDefault()

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

稍後你將看到其他修飾符的示例,當探索那些功能時,我們將討論 v-onv-model 的修飾符。

最後,這裡是完整的指令語法的視覺化表示

directive syntax graph

模板語法已載入