[TOC]
# 模板語法
Vue.js 使用了基于 HTML 的模板語法,允許開發者聲明式地將 DOM 綁定至底層 Vue 實例的數據。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規范的瀏覽器和 HTML 解析器解析。
在底層的實現上,Vue 將模板編譯成虛擬 DOM 渲染函數。結合響應系統,Vue 能夠智能地計算出最少需要重新渲染多少組件,并把 DOM 操作次數減到最少。
如果你熟悉虛擬 DOM 并且偏愛 JavaScript 的原始力量,你也可以不用模板,[直接寫渲染 (render) 函數](https://cn.vuejs.org/v2/guide/render-function.html),使用可選的 JSX 語法。
## 插值
### 文本
數據綁定最常見的形式就是使用“Mustache”語法 (雙大括號) 的文本插值:
~~~
<span>Message: {{ msg }}</span>
~~~
Mustache 標簽將會被替代為對應數據對象上`msg`屬性的值。無論何時,綁定的數據對象上`msg`屬性發生了改變,插值處的內容都會更新。
通過使用[v-once 指令](https://cn.vuejs.org/v2/api/#v-once),你也能執行一次性地插值,當數據改變時,插值處的內容不會更新。但請留心這會影響到該節點上的其它數據綁定:
~~~
<span v-once>這個將不會改變: {{ msg }}</span>
~~~
### 原始 HTML
雙大括號會將數據解釋為普通文本,而非 HTML 代碼。為了輸出真正的 HTML,你需要使用`v-html`指令:
~~~
<p>Using mustaches: {{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
~~~
Using mustaches: This should be red.
Using v-html directive:This should be red.
這個`span`的內容將會被替換成為屬性值`rawHtml`,直接作為 HTML——會忽略解析屬性值中的數據綁定。注意,你不能使用`v-html`來復合局部模板,因為 Vue 不是基于字符串的模板引擎。反之,對于用戶界面 (UI),組件更適合作為可重用和可組合的基本單位。
你的站點上動態渲染的任意 HTML 可能會非常危險,因為它很容易導致[XSS 攻擊](https://en.wikipedia.org/wiki/Cross-site_scripting)。請只對可信內容使用 HTML 插值,**絕不要**對用戶提供的內容使用插值。
### 特性
Mustache 語法不能作用在 HTML 特性上,遇到這種情況應該使用[v-bind 指令](https://cn.vuejs.org/v2/api/#v-bind):
~~~
<div v-bind:id="dynamicId"></div>
~~~
在布爾特性的情況下,它們的存在即暗示為`true`,`v-bind`工作起來略有不同,在這個例子中:
~~~
<button v-bind:disabled="isButtonDisabled">Button</button>
~~~
如果`isButtonDisabled`的值是`null`、`undefined`或`false`,則`disabled`特性甚至不會被包含在渲染出來的`<button>`元素中。
### 使用 JavaScript 表達式
迄今為止,在我們的模板中,我們一直都只綁定簡單的屬性鍵值。但實際上,對于所有的數據綁定,Vue.js 都提供了完全的 JavaScript 表達式支持。
~~~
{{ number + 1 }}
{{ ok ? 'YES' : 'NO' }}
{{ message.split('').reverse().join('') }}
<div v-bind:id="'list-' + id"></div>
~~~
這些表達式會在所屬 Vue 實例的數據作用域下作為 JavaScript 被解析。有個限制就是,每個綁定都只能包含**單個表達式**,所以下面的例子都**不會**生效。
~~~
<!-- 這是語句,不是表達式 -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}
~~~
模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如`Math`和`Date`。你不應該在模板表達式中試圖訪問用戶定義的全局變量。
## 指令
指令 (Directives) 是帶有`v-`前綴的特殊特性。指令特性的值預期是**單個 JavaScript 表達式**(`v-for`是例外情況,稍后我們再討論)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地作用于 DOM。回顧我們在介紹中看到的例子:
~~~
<p v-if="seen">現在你看到我了</p>
~~~
這里,`v-if`指令將根據表達式`seen`的值的真假來插入/移除`<p>`元素。
### 參數
一些指令能夠接收一個“參數”,在指令名稱之后以冒號表示。例如,`v-bind`指令可以用于響應式地更新 HTML 特性:
~~~
<a v-bind:href="url">...</a>
~~~
在這里`href`是參數,告知`v-bind`指令將該元素的`href`特性與表達式`url`的值綁定。
另一個例子是`v-on`指令,它用于監聽 DOM 事件:
~~~
<a v-on:click="doSomething">...</a>
~~~
在這里參數是監聽的事件名。我們也會更詳細地討論事件處理。
### 動態參數
> 2.6.0 新增
從 2.6.0 開始,可以用方括號括起來的 JavaScript 表達式作為一個指令的參數:
~~~
<a v-bind:[attributeName]="url"> ... </a>
~~~
這里的`attributeName`會被作為一個 JavaScript 表達式進行動態求值,求得的值將會作為最終的參數來使用。例如,如果你的 Vue 實例有一個`data`屬性`attributeName`,其值為`"href"`,那么這個綁定將等價于`v-bind:href`。
同樣地,你可以使用動態參數為一個動態的事件名綁定處理函數:
~~~
<a v-on:[eventName]="doSomething"> ... </a>
~~~
同樣地,當`eventName`的值為`"focus"`時,`v-on:[eventName]`將等價于`v-on:focus`。
#### 對動態參數的值的約束
動態參數預期會求出一個字符串,異常情況下值為`null`。這個特殊的`null`值可以被顯性地用于移除綁定。任何其它非字符串類型的值都將會觸發一個警告。
動態參數表達式有一些語法約束,因為某些字符,例如空格和引號,放在 HTML 特性名里是無效的。同樣,在 DOM 中使用模板時你需要回避大寫鍵名。
例如,下面的代碼是無效的:
~~~
<!-- 這會觸發一個編譯警告 -->
<a v-bind:['foo' + bar]="value"> ... </a>
~~~
變通的辦法是使用沒有空格或引號的表達式,或用計算屬性替代這種復雜表達式。
另外,如果你在 DOM 中使用模板 (直接在一個 HTML 文件里撰寫模板),需要留意瀏覽器會把特性名全部強制轉為小寫:
~~~
<!-- 在 DOM 中使用模板時這段代碼會被轉換為 `v-bind:[someattr]` -->
<a v-bind:[someAttr]="value"> ... </a>
~~~
### 修飾符
修飾符 (modifier) 是以半角句號`.`指明的特殊后綴,用于指出一個指令應該以特殊方式綁定。例如,`.prevent`修飾符告訴`v-on`指令對于觸發的事件調用`event.preventDefault()`:
~~~
<form v-on:submit.prevent="onSubmit">...</form>
~~~
在接下來對[`v-on`](https://cn.vuejs.org/v2/guide/events.html#%E4%BA%8B%E4%BB%B6%E4%BF%AE%E9%A5%B0%E7%AC%A6)和[`v-for`](https://cn.vuejs.org/v2/guide/forms.html#%E4%BF%AE%E9%A5%B0%E7%AC%A6)等功能的探索中,你會看到修飾符的其它例子。
## [縮寫](https://cn.vuejs.org/v2/guide/syntax.html#%E7%BC%A9%E5%86%99 "縮寫")
`v-`前綴作為一種視覺提示,用來識別模板中 Vue 特定的特性。當你在使用 Vue.js 為現有標簽添加動態行為 (dynamic behavior) 時,`v-`前綴很有幫助,然而,對于一些頻繁用到的指令來說,就會感到使用繁瑣。同時,在構建由 Vue 管理所有模板的[單頁面應用程序 (SPA - single page application)](https://en.wikipedia.org/wiki/Single-page_application)時,`v-`前綴也變得沒那么重要了。因此,Vue 為`v-bind`和`v-on`這兩個最常用的指令,提供了特定簡寫:
### [`v-bind`縮寫](https://cn.vuejs.org/v2/guide/syntax.html#v-bind-%E7%BC%A9%E5%86%99 "v-bind 縮寫")
~~~
<!-- 完整語法 -->
<a v-bind:href="url">...</a>
<!-- 縮寫 -->
<a :href="url">...</a>
~~~
### [`v-on`縮寫](https://cn.vuejs.org/v2/guide/syntax.html#v-on-%E7%BC%A9%E5%86%99 "v-on 縮寫")
~~~
<!-- 完整語法 -->
<a v-on:click="doSomething">...</a>
<!-- 縮寫 -->
<a @click="doSomething">...</a>
~~~
它們看起來可能與普通的 HTML 略有不同,但`:`與`@`對于特性名來說都是合法字符,在所有支持 Vue 的瀏覽器都能被正確地解析。而且,它們不會出現在最終渲染的標記中。縮寫語法是完全可選的,但隨著你更深入地了解它們的作用,你會慶幸擁有它們。
- 內容介紹
- EcmaScript基礎
- 快速入門
- 常量與變量
- 字符串
- 函數的基本概念
- 條件判斷
- 數組
- 循環
- while循環
- for循環
- 函數基礎
- 對象
- 對象的方法
- 函數
- 變量作用域
- 箭頭函數
- 閉包
- 高階函數
- map/reduce
- filter
- sort
- Promise
- 基本對象
- Arguments 對象
- 剩余參數
- Map和Set
- Json基礎
- RegExp
- Date
- async
- callback
- promise基礎
- promise-api
- promise鏈
- async-await
- 項目實踐
- 標簽系統
- 遠程API請求
- 面向對象編程
- 創建對象
- 原型繼承
- 項目實踐
- Classes
- 構造函數
- extends
- static
- 項目實踐
- 模塊
- import
- export
- 項目實踐
- 第三方擴展庫
- immutable
- Vue快速入門
- 理解MVVM
- Vue中的MVVM模型
- Webpack+Vue快速入門
- 模板語法
- 計算屬性和偵聽器
- Class 與 Style 綁定
- 條件渲染
- 列表渲染
- 事件處理
- 表單輸入綁定
- 組件基礎
- 組件注冊
- Prop
- 自定義事件
- 插槽
- 混入
- 過濾器
- 項目實踐
- 標簽編輯
- 移動客戶端開發
- uni-app基礎
- 快速入門程序
- 單頁程序
- 底部Tab導航
- Vue語法基礎
- 模版語法
- 計算屬性與偵聽器
- Class與Style綁定
- 樣式與布局
- Box模型
- Flex布局
- 內置指令
- 基本指令
- v-model與表單
- 條件渲染指令
- 列表渲染指令v-for
- 事件與自定義屬性
- 生命周期
- 項目實踐
- 學生實驗
- 貝店商品列表
- 加載更多數據
- 詳情頁面
- 自定義組件
- 內置組件
- 表單組件
- 技術專題
- 狀態管理vuex
- Flyio
- Mockjs
- SCSS
- 條件編譯
- 常用功能實現
- 上拉加載更多數據
- 數據加載綜合案例
- Teaset UI組件庫
- Teaset設計
- Teaset使用基礎
- ts-tag
- ts-badge
- ts-button
- ta-banner
- ts-list
- ts-icon
- ts-load-more
- ts-segmented-control
- 代碼模版
- 項目實踐
- 標簽組件
- 失物招領客戶端原型
- 發布頁面
- 檢索頁面
- 詳情頁面
- 服務端開發技術
- 服務端開發環境配置
- Koajs快速入門
- 快速入門
- 常用Koa中間件介紹
- 文件上傳
- RestfulApi
- 一個復雜的RESTful例子
- 使用Mockjs生成模擬數據
- Thinkjs快速入門
- MVC模式
- Thinkjs介紹
- 快速入門
- RESTful服務
- RBAC案例
- 關聯模型
- 應用開發框架
- 服務端開發
- PC端管理界面開發
- 移動端開發
- 項目實踐
- 失物招領項目
- 移動客戶端UI設計
- 服務端設計
- 數據庫設計
- Event(事件)
- 客戶端設計
- 事件列表頁面
- 發布頁面
- 事件詳情頁面
- API設計
- image
- event
- 微信公眾號開發
- ui設計規范