1. Vue 實(shí)例
1.1 創(chuàng)建一個(gè)Vue實(shí)例
一個(gè) Vue 應(yīng)用由一個(gè)通過 new Vue 創(chuàng)建的根 Vue 實(shí)例,以及可選的嵌套的、可復(fù)用的組件樹組成。demo
1.2 數(shù)據(jù)與方法
數(shù)據(jù)的響應(yīng)式渲染
當(dāng)一個(gè) Vue 實(shí)例被創(chuàng)建時(shí),它向 Vue 的響應(yīng)式系統(tǒng)中加入了其 data 對(duì)象中能找到的所有的屬性。當(dāng)這些屬性的值發(fā)生改變時(shí),視圖將會(huì)產(chǎn)生“響應(yīng)”,即匹配更新為新的值。(注意的是只有當(dāng)實(shí)例被創(chuàng)建時(shí) data 中存在的屬性才是響應(yīng)式的。)
使用 Object.freeze(),這會(huì)阻止修改現(xiàn)有的屬性,也意味著響應(yīng)系統(tǒng)無法再追蹤變化。demo
實(shí)例屬性與方法
除了數(shù)據(jù)屬性,Vue 實(shí)例還暴露了一些有用的實(shí)例屬性與方法。它們都有前綴 $,以便與用戶定義的屬性區(qū)分開來。demo
1.3 實(shí)例生命周期鉤子
每個(gè) Vue 實(shí)例在被創(chuàng)建時(shí)都要經(jīng)過一系列的初始化過程——例如,需要設(shè)置數(shù)據(jù)監(jiān)聽、編譯模板、將實(shí)例掛載到 DOM 并在數(shù)據(jù)變化時(shí)更新 DOM 等。同時(shí)在這個(gè)過程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù),這給了用戶在不同階段添加自己的代碼的機(jī)會(huì)。
beforeCreate created beforeMount mounted beforeUpdate updated beforeDestroy destroyed 8個(gè)聲明周期
生命周期鉤子的 this 上下文指向調(diào)用它的 Vue 實(shí)例。注意:不要在選項(xiàng)屬性或回調(diào)上使用箭頭函數(shù),會(huì)改變this指向。
2. 模版語法
2.1插值
文本
使用“Mustache”語法 (雙大括號(hào)) 的文本插值demo, 一次性插值,當(dāng)數(shù)據(jù)改變時(shí),插值處的內(nèi)容不會(huì)更新demo。
原始HTML
輸出真正的 HTML,你需要使用 v-html 指令demo注意:你的站點(diǎn)上動(dòng)態(tài)渲染的任意 HTML 可能會(huì)非常危險(xiǎn),因?yàn)樗苋菀讓?dǎo)致 XSS 攻擊。請(qǐng)只對(duì)可信內(nèi)容使用 HTML 插值,絕不要對(duì)用戶提供的內(nèi)容使用插值。
特性
Mustache 語法不能作用在 HTML 特性上,遇到這種情況應(yīng)該使用 v-bind 指令demo當(dāng)綁定屬性值為null、undefined 或 false特性甚至不會(huì)被包含在渲染出來的元素中demo
使用 JavaScript 表達(dá)式
對(duì)于所有的數(shù)據(jù)綁定,Vue.js 都提供了完全的 JavaScript 表達(dá)式支持demo。限制,每個(gè)綁定都只能包含單個(gè)表達(dá)式,語句不生效。注意:模板表達(dá)式都被放在沙盒中,只能訪問全局變量的一個(gè)白名單,如 Math 和 Date 。你不應(yīng)該在模板表達(dá)式中試圖訪問用戶定義的全局變量。
2.2 指令
指令 (Directives) 是帶有 v- 前綴的特殊特性。指令特性的值預(yù)期是單個(gè) JavaScript 表達(dá)式(v-for 是例外情況,稍后我們?cè)儆懻?。指令的職責(zé)是,當(dāng)表達(dá)式的值改變時(shí),將其產(chǎn)生的連帶影響,響應(yīng)式地作用于 DOM。
參數(shù) 一些指令能夠接收一個(gè)“參數(shù)”,在指令名稱之后以冒號(hào)表示。例如,v-bind 指令可以用于響應(yīng)式地更新 HTML 特性demo
修飾符 . 指明的特殊后綴,用于指出一個(gè)指令應(yīng)該以特殊方式綁定。如.prevent組織form提交默認(rèn)行為demo
縮寫 v-bind縮寫 : , v-on縮寫 @
3. 計(jì)算屬性和偵聽器
3.1 計(jì)算屬性
在模版中使用表達(dá)式,不易于觀察,可使用計(jì)算屬性代替。對(duì)于任何復(fù)雜邏輯,你都應(yīng)當(dāng)使用計(jì)算屬性。
一個(gè)基礎(chǔ)的例子demo,你可以像綁定普通屬性一樣在模板中綁定計(jì)算屬性。
計(jì)算屬性緩存 vs 方法
demo兩種方式的最終結(jié)果確實(shí)是完全相同的。然而,不同的是計(jì)算屬性是基于它們的依賴進(jìn)行緩存的。計(jì)算屬性只有在它的相關(guān)依賴發(fā)生改變時(shí)才會(huì)重新求值。這就意味著只要 message 還沒有發(fā)生改變,多次訪問 reversedMessage 計(jì)算屬性會(huì)立即返回之前的計(jì)算結(jié)果,而不必再次執(zhí)行函數(shù)。相比之下,每當(dāng)觸發(fā)重新渲染時(shí),調(diào)用方法將總會(huì)再次執(zhí)行函數(shù)。
我們?yōu)槭裁葱枰彺?/strong>?假設(shè)我們有一個(gè)性能開銷比較大的計(jì)算屬性 A,它需要遍歷一個(gè)巨大的數(shù)組并做大量的計(jì)算。然后我們可能有其他的計(jì)算屬性依賴于 A 。如果沒有緩存,我們將不可避免的多次執(zhí)行 A 的 getter!如果你不希望有緩存,請(qǐng)用方法來替代。
計(jì)算屬性 vs 偵聽屬性
偵聽屬性:觀察和響應(yīng) Vue 實(shí)例上的數(shù)據(jù)變動(dòng)。當(dāng)你有一些數(shù)據(jù)需要隨著其它數(shù)據(jù)變動(dòng)而變動(dòng)時(shí),你很容易濫用 watch。然而,通常更好的做法是使用計(jì)算屬性而不是命令式的 watch 回調(diào)。watch的例子 改成計(jì)算屬性后
計(jì)算屬性的 setter
計(jì)算屬性默認(rèn)只有 getter ,不過在需要時(shí)你也可以提供一個(gè) setter。demo
3.2 偵聽器
雖然計(jì)算屬性在大多數(shù)情況下更合適,但有時(shí)也需要一個(gè)自定義的偵聽器。這就是為什么 Vue 通過 watch 選項(xiàng)提供了一個(gè)更通用的方法,來響應(yīng)數(shù)據(jù)的變化。當(dāng)需要在數(shù)據(jù)變化時(shí)執(zhí)行異步或開銷較大的操作時(shí),這個(gè)方式是最有用的。demo 除了 watch 選項(xiàng)之外,您還可以使用命令式的 vm.$watch API。
4. Class 與 Style 綁定
操作元素的 class 列表和內(nèi)聯(lián)樣式是數(shù)據(jù)綁定的一個(gè)常見需求。因?yàn)樗鼈兌际菍傩裕晕覀兛梢杂?v-bind 處理它們:只需要通過表達(dá)式計(jì)算出字符串結(jié)果即可。不過,字符串拼接麻煩且易錯(cuò)。因此,在將 v-bind 用于 class 和 style 時(shí),Vue.js 做了專門的增強(qiáng)。表達(dá)式結(jié)果的類型除了字符串之外,還可以是對(duì)象或數(shù)組。
4.1 綁定 HTML Class
對(duì)象語法
傳給 v-bind:class 一個(gè)對(duì)象,以動(dòng)態(tài)地切換 class demo , v-bind:class 指令也可以與普通的 class 屬性共存demo
綁定的數(shù)據(jù)對(duì)象不必內(nèi)聯(lián)定義在模板里demo,綁定一個(gè)返回對(duì)象的計(jì)算屬性。這是一個(gè)常用且強(qiáng)大的模式demo
數(shù)組語法
我們可以把一個(gè)數(shù)組傳給 v-bind:class,以應(yīng)用一個(gè) class 列表demo,根據(jù)條件切換列表中的 class,可以用三元表達(dá)式demo當(dāng)有多個(gè)條件 class 時(shí)這樣寫有些繁瑣。所以在數(shù)組語法中也可以使用對(duì)象語法demo
用在組件上
當(dāng)在一個(gè)自定義組件上使用 class 屬性時(shí),這些類將被添加到該組件的根元素上面。這個(gè)元素上已經(jīng)存在的類不會(huì)被覆蓋。demo
對(duì)于帶數(shù)據(jù)綁定 class 也同樣適用demo。
4.2 綁定內(nèi)聯(lián)樣式
對(duì)象語法
v-bind:style 的對(duì)象語法十分直觀——看著非常像 CSS,但其實(shí)是一個(gè) JavaScript 對(duì)象。CSS 屬性名可以用駝峰式 (camelCase) 或短橫線分隔 (kebab-case,記得用單引號(hào)括起來) 來命名demo。,直接綁定到一個(gè)樣式對(duì)象通常更好,這會(huì)讓模板更清晰demo,同樣的,對(duì)象語法常常結(jié)合返回對(duì)象的計(jì)算屬性使用。
數(shù)組語法
v-bind:style 的數(shù)組語法可以將多個(gè)樣式對(duì)象應(yīng)用到同一個(gè)元素上 demo
自動(dòng)添加前綴
當(dāng) v-bind:style 使用需要添加瀏覽器引擎前綴的 CSS 屬性時(shí),如 transform,Vue.js 會(huì)自動(dòng)偵測(cè)并添加相應(yīng)的前綴。
多重值
從 2.3.0 ,可以為 style 綁定中的屬性提供一個(gè)包含多個(gè)值的數(shù)組,常用于提供多個(gè)帶前綴的值。demo
5. 條件渲染
5.1 v-if
在<template>
元素上使用 v-if 條件渲染分組
v-if 指令必須添加到一個(gè)元素上,如果想切換元素,可以把一個(gè) <template>
元素當(dāng)做不可見的包裹元素,并在上面使用 v-if。最終的渲染結(jié)果將不包含 <template>
元素。demo
v-else
使用 v-else 指令來表示 v-if 的“else 塊”demo
v-else 元素必須緊跟在帶 v-if 或者 v-else-if 的元素的后面,否則它將不會(huì)被識(shí)別。
v-else-if
v-else-if,顧名思義,充當(dāng) v-if 的“else-if 塊”,可以連續(xù)使用demo
類似于 v-else,v-else-if 也必須緊跟在帶 v-if 或者 v-else-if 的元素之后。
用 key 管理可復(fù)用的元素
Vue 會(huì)盡可能高效地渲染元素,通常會(huì)復(fù)用已有元素而不是從頭開始渲染。這么做除了使 Vue 變得非常快之外,還有其它一些好處。例如,如果你允許用戶在不同的登錄方式之間切換demo,代碼中切換 loginType 將不會(huì)清除用戶已經(jīng)輸入的內(nèi)容。因?yàn)閮蓚€(gè)模板使用了相同的元素,<input>
不會(huì)被替換掉——僅僅是替換了它的 placeholder。
這樣也不總是符合實(shí)際需求,所以 Vue 為你提供了一種方式來表達(dá)“這兩個(gè)元素是完全獨(dú)立的,不要復(fù)用它們”。只需添加一個(gè)具有唯一值的 key 屬性即可demo,注意,<label>
元素仍然會(huì)被高效地復(fù)用,因?yàn)樗鼈儧]有添加 key 屬性。
5.2 v-show
另一個(gè)用于根據(jù)條件展示元素的選項(xiàng)是 v-show 指令。用法大致一樣demo, 不同的是帶有 v-show 的元素始終會(huì)被渲染并保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。注意,v-show 不支持 <template>
元素,也不支持 v-else。
5.3 v-if vs v-show
v-if 是“真正”的條件渲染,因?yàn)樗鼤?huì)確保在切換過程中條件塊內(nèi)的事件監(jiān)聽器和子組件適當(dāng)?shù)乇讳N毀和重建。
v-if 也是惰性的:如果在初始渲染時(shí)條件為假,則什么也不做——直到條件第一次變?yōu)檎鏁r(shí),才會(huì)開始渲染條件塊。
相比之下,v-show 就簡單得多——不管初始條件是什么,元素總是會(huì)被渲染,并且只是簡單地基于 CSS 進(jìn)行切換。
一般來說,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show 較好;如果在運(yùn)行時(shí)條件很少改變,則使用 v-if 較好。
5.4 v-if 與 v-for 一起使用
當(dāng) v-if 與 v-for 一起使用時(shí),v-for 具有比 v-if 更高的優(yōu)先級(jí)。
6. 列表渲染
6.1 用 v-for 把一個(gè)數(shù)組對(duì)應(yīng)為一組元素
我們用 v-for 指令根據(jù)一組數(shù)組的選項(xiàng)列表進(jìn)行渲染。v-for 指令需要使用 item in items 形式的特殊語法,items 是源數(shù)據(jù)數(shù)組并且 item 是數(shù)組元素迭代的別名demo 。在 v-for 塊中,我們擁有對(duì)父作用域?qū)傩缘耐耆L問權(quán)限。v-for 還支持一個(gè)可選的第二個(gè)參數(shù)為當(dāng)前項(xiàng)的索引demo。你也可以用 of 替代 in 作為分隔符,因?yàn)樗亲罱咏?JavaScript 迭代器的語法demo。
6.2 一個(gè)對(duì)象的 v-for
你也可以用 v-for 通過一個(gè)對(duì)象的屬性來迭代demo。你也可以提供第二個(gè)的參數(shù)為鍵名 demo。第三個(gè)參數(shù)為索引demo。 注意,在遍歷對(duì)象時(shí),是按 Object.keys() 的結(jié)果遍歷,但是不能保證它的結(jié)果在不同的 JavaScript 引擎下是一致的。
6.3 key
當(dāng) Vue.js 用 v-for 正在更新已渲染過的元素列表時(shí),它默認(rèn)用“就地復(fù)用”策略。如果數(shù)據(jù)項(xiàng)的順序被改變,Vue 將不會(huì)移動(dòng) DOM 元素來匹配數(shù)據(jù)項(xiàng)的順序, 而是簡單復(fù)用此處每個(gè)元素,并且確保它在特定索引下顯示已被渲染過的每個(gè)元素。
這個(gè)默認(rèn)的模式是高效的,但是只適用于不依賴子組件狀態(tài)或臨時(shí) DOM 狀態(tài) (例如:表單輸入值) 的列表渲染輸出。
為了給 Vue 一個(gè)提示,以便它能跟蹤每個(gè)節(jié)點(diǎn)的身份,從而重用和重新排序現(xiàn)有元素,你需要為每項(xiàng)提供一個(gè)唯一 key 屬性。理想的 key 值是每項(xiàng)都有的且唯一的 id。
<div v-for="item in items" :key="item.id">
<!-- 內(nèi)容 -->
</div>
建議盡可能在使用 v-for 時(shí)提供 key,除非遍歷輸出的 DOM 內(nèi)容非常簡單,或者是刻意依賴默認(rèn)行為以獲取性能上的提升。
因?yàn)樗?Vue 識(shí)別節(jié)點(diǎn)的一個(gè)通用機(jī)制,key 并不與 v-for 特別關(guān)聯(lián),key 還具有其他用途。
6.4 數(shù)組更新檢測(cè)
變異方法
Vue 包含一組觀察數(shù)組的變異方法,所以它們也將會(huì)觸發(fā)視圖更新。這些方法如下:
push()pop()shift()unshift()splice()sort()reverse()
你打開控制臺(tái),然后用前面例子的 items 數(shù)組調(diào)用變異方法:example1.items.push({ message: 'Baz' }) 。
替換數(shù)組
變異方法 (mutation method),顧名思義,會(huì)改變被這些方法調(diào)用的原始數(shù)組。相比之下,也有非變異 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。這些不會(huì)改變?cè)紨?shù)組,但總是返回一個(gè)新數(shù)組。當(dāng)使用非變異方法時(shí),可以用新數(shù)組替換舊數(shù)組
example1.items = example1.items.filter(function (item) {
return item.message.match(/Foo/)
})
你可能認(rèn)為這將導(dǎo)致 Vue 丟棄現(xiàn)有 DOM 并重新渲染整個(gè)列表。幸運(yùn)的是,事實(shí)并非如此。Vue 為了使得 DOM 元素得到最大范圍的重用而實(shí)現(xiàn)了一些智能的、啟發(fā)式的方法,所以用一個(gè)含有相同元素的數(shù)組去替換原來的數(shù)組是非常高效的操作。
注意事項(xiàng)
由于 JavaScript 的限制,Vue 不能檢測(cè)以下變動(dòng)的數(shù)組:
當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí),例如:vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長度時(shí),例如:vm.items.length = newLength
舉個(gè)例子:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是響應(yīng)性的
vm.items.length = 2 // 不是響應(yīng)性的
為了解決第一類問題,以下兩種方式都可以實(shí)現(xiàn)和 vm.items[indexOfItem] = newValue 相同的效果,同時(shí)也將觸發(fā)狀態(tài)更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 實(shí)例方法,該方法是全局方法 Vue.set 的一個(gè)別名:
vm.$set(vm.items, indexOfItem, newValue)
為了解決第二類問題,你可以使用 splice:
vm.items.splice(newLength)
6.5 對(duì)象更改檢測(cè)注意事項(xiàng)
還是由于 JavaScript 的限制,Vue 不能檢測(cè)對(duì)象屬性的添加或刪除demo。對(duì)于已經(jīng)創(chuàng)建的實(shí)例,Vue 不能動(dòng)態(tài)添加根級(jí)別的響應(yīng)式屬性。但是,可以使用 Vue.set(object, key, value) 方法向嵌套對(duì)象添加響應(yīng)式屬性。你還可以使用 vm.$set 實(shí)例方法,它只是全局 Vue.set 的別名demo。有時(shí)你可能需要為已有對(duì)象賦予多個(gè)新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應(yīng)該用兩個(gè)對(duì)象的屬性創(chuàng)建一個(gè)新的對(duì)象。所以,如果你想添加新的響應(yīng)式屬性,不要這樣做demo你應(yīng)該這樣做demo。
6.6 顯示過濾/排序結(jié)果
有時(shí),我們想要顯示一個(gè)數(shù)組的過濾或排序副本,而不實(shí)際改變或重置原始數(shù)據(jù)。在這種情況下,可以創(chuàng)建返回過濾或排序數(shù)組的計(jì)算屬性demo。在計(jì)算屬性不適用的情況下 (例如,在嵌套 v-for 循環(huán)中) 你可以使用一個(gè) method 方法demo。
6.7 一段取值范圍的 v-for
v-for 也可以取整數(shù)。在這種情況下,它將重復(fù)多次模板demo。
6.8 v-for on a <template>
類似于 v-if,你也可以利用帶有 v-for 的 <template>
渲染多個(gè)元素demo。
6.9 v-for with v-if
當(dāng)它們處于同一節(jié)點(diǎn),v-for 的優(yōu)先級(jí)比 v-if 更高,這意味著 v-if 將分別重復(fù)運(yùn)行于每個(gè) v-for 循環(huán)中。當(dāng)你想為僅有的一些項(xiàng)渲染節(jié)點(diǎn)時(shí),這種優(yōu)先級(jí)的機(jī)制會(huì)十分有用demo。而如果你的目的是有條件地跳過循環(huán)的執(zhí)行,那么可以將 v-if 置于外層元素 (或 <template>
)上demo。
6.10 一個(gè)組件的 v-for
在自定義組件里,你可以像任何普通元素一樣用 v-for 。然而,任何數(shù)據(jù)都不會(huì)被自動(dòng)傳遞到組件里,因?yàn)榻M件有自己獨(dú)立的作用域。為了把迭代數(shù)據(jù)傳遞到組件里,我們要用 props。demo
7. 事件處理
7.1 監(jiān)聽事件
可以用 v-on 指令監(jiān)聽 DOM 事件,并在觸發(fā)時(shí)運(yùn)行一些 JavaScript 代碼。demo
7.2 事件處理方法
然而許多事件處理邏輯會(huì)更為復(fù)雜,所以直接把 JavaScript 代碼寫在 v-on 指令中是不可行的。因此 v-on 還可以接收一個(gè)需要調(diào)用的方法名稱。demo
7.3 內(nèi)聯(lián)處理器中的方法
除了直接綁定到一個(gè)方法,也可以在內(nèi)聯(lián) JavaScript 語句中調(diào)用方法demo
有時(shí)也需要在內(nèi)聯(lián)語句處理器中訪問原始的 DOM 事件。可以用特殊變量 $event 把它傳入方法demo
7.4 事件修飾符
在事件處理程序中調(diào)用 event.preventDefault() 或 event.stopPropagation() 是非常常見的需求。盡管我們可以在方法中輕松實(shí)現(xiàn)這點(diǎn),但更好的方式是:方法只有純粹的數(shù)據(jù)邏輯,而不是去處理 DOM 事件細(xì)節(jié)。為了解決這個(gè)問題,Vue.js 為 v-on 提供了事件修飾符。之前提過,修飾符是由點(diǎn)開頭的指令后綴來表示的。
.stop .prevent .capture .self .once .passive demo
使用修飾符時(shí),順序很重要;相應(yīng)的代碼會(huì)以同樣的順序產(chǎn)生。因此,用 v-on:click.prevent.self 會(huì)阻止所有的點(diǎn)擊,而 v-on:click.self.prevent 只會(huì)阻止對(duì)元素自身的點(diǎn)擊。
Vue 還對(duì)應(yīng) addEventListener 中的 passive 選項(xiàng)提供了 .passive 修飾符 demo。這個(gè) .passive 修飾符尤其能夠提升移動(dòng)端的性能。
注意,不要把 .passive 和 .prevent 一起使用,因?yàn)?.prevent 將會(huì)被忽略,同時(shí)瀏覽器可能會(huì)向你展示一個(gè)警告。請(qǐng)記住,.passive 會(huì)告訴瀏覽器你不想阻止事件的默認(rèn)行為。
7.5 按鍵修飾符
在監(jiān)聽鍵盤事件時(shí),我們經(jīng)常需要檢查常見的鍵值。Vue 允許為 v-on 在監(jiān)聽鍵盤事件時(shí)添加按鍵修飾符demo,記住所有的 keyCode 比較困難,所以 Vue 為最常用的按鍵提供了別名,如.enter demo。
全部的按鍵別名:.enter .tab .delete (捕獲“刪除”和“退格”鍵) .esc .space .up .down .left .right
可以通過全局 config.keyCodes 對(duì)象自定義按鍵修飾符別名demo。
自動(dòng)匹配按鍵修飾符
你也可直接將 KeyboardEvent.key 暴露的任意有效按鍵名轉(zhuǎn)換為 kebab-case 來作為修飾符
<input @keyup.page-down="onPageDown">
在上面的例子中,處理函數(shù)僅在 $event.key === 'PageDown' 時(shí)被調(diào)用。
注意,有一些按鍵 (.esc 以及所有的方向鍵) 在 IE9 中有不同的 key 值, 如果你想支持 IE9,它們的內(nèi)置別名應(yīng)該是首選。
7.6 系統(tǒng)修飾鍵
可以用如下修飾符來實(shí)現(xiàn)僅在按下相應(yīng)按鍵時(shí)才觸發(fā)鼠標(biāo)或鍵盤事件的監(jiān)聽器。
.ctrl .alt .shift .meta demo
鼠標(biāo)按鈕修飾符
2.2.0 新增 .left .right .middle 這些修飾符會(huì)限制處理函數(shù)僅響應(yīng)特定的鼠標(biāo)按鈕。
7.7 為什么在 HTML 中監(jiān)聽事件?
你可能注意到這種事件監(jiān)聽的方式違背了關(guān)注點(diǎn)分離 (separation of concern) 這個(gè)長期以來的優(yōu)良傳統(tǒng)。但不必?fù)?dān)心,因?yàn)樗械?Vue.js 事件處理方法和表達(dá)式都嚴(yán)格綁定在當(dāng)前視圖的 ViewModel 上,它不會(huì)導(dǎo)致任何維護(hù)上的困難。實(shí)際上,使用 v-on 有幾個(gè)好處:
掃一眼 HTML 模板便能輕松定位在 JavaScript 代碼里對(duì)應(yīng)的方法。
因?yàn)槟銦o須在 JavaScript 里手動(dòng)綁定事件,你的 ViewModel 代碼可以是非常純粹的邏輯,和 DOM 完全解耦,更易于測(cè)試。
當(dāng)一個(gè) ViewModel 被銷毀時(shí),所有的事件處理器都會(huì)自動(dòng)被刪除。你無須擔(dān)心如何自己清理它們。
8. 表單輸入綁定
8.1 基礎(chǔ)用法
用 v-model 指令在表單 <input>
及 <textarea>
元素上創(chuàng)建雙向數(shù)據(jù)綁定。它會(huì)根據(jù)控件類型自動(dòng)選取正確的方法來更新元素。 v-model 本質(zhì)上是語法糖。它負(fù)責(zé)監(jiān)聽用戶的輸入事件以更新數(shù)據(jù),并對(duì)一些極端場景進(jìn)行一些特殊處理。
v-model 會(huì)忽略所有表單元素的 value、checked、selected 特性的初始值而總是將 Vue 實(shí)例的數(shù)據(jù)作為數(shù)據(jù)來源。你應(yīng)該通過 JavaScript 在組件的 data 選項(xiàng)中聲明初始值。
對(duì)于需要使用輸入法 (如中文、日文、韓文等) 的語言,你會(huì)發(fā)現(xiàn) v-model 不會(huì)在輸入法組合文字過程中得到更新。如果你也想處理這個(gè)過程,請(qǐng)使用 input 事件。
文本demo
多行文本demo 在文本區(qū)域插值 (<textarea></textarea>
) 并不會(huì)生效,應(yīng)用 v-model 來代替。
復(fù)選框 單個(gè)復(fù)選框,綁定到布爾值單個(gè)復(fù)選框,綁定到布爾值demo。多個(gè)復(fù)選框,綁定到同一個(gè)數(shù)組demo
單選按鈕demo
選擇框 單選時(shí)demo 多選時(shí) (綁定到一個(gè)數(shù)組)demo 用 v-for 渲染的動(dòng)態(tài)選項(xiàng)demo
如果 v-model 表達(dá)式的初始值未能匹配任何選項(xiàng),<select>
元素將被渲染為“未選中”狀態(tài)。在 iOS 中,這會(huì)使用戶無法選擇第一個(gè)選項(xiàng)。因?yàn)檫@樣的情況下,iOS 不會(huì)觸發(fā) change 事件。因此,更推薦像上面這樣提供一個(gè)值為空的禁用選項(xiàng)。
8.2 值綁定
復(fù)選框demo
這里的 true-value 和 false-value 特性并不會(huì)影響輸入控件的 value 特性,因?yàn)闉g覽器在提交表單時(shí)并不會(huì)包含未被選中的復(fù)選框。如果要確保表單中這兩個(gè)值中的一個(gè)能夠被提交,(比如“yes”或“no”),請(qǐng)換用單選按鈕。
單選按鈕 demo
選擇框的選項(xiàng)demo
8.3 修飾符
.lazy 添加 lazy 修飾符,是v-model轉(zhuǎn)變?yōu)槭褂?change 事件進(jìn)行同步demo實(shí)時(shí)更新
.number 自動(dòng)將用戶的輸入值轉(zhuǎn)為數(shù)值類型demo
.trim 自動(dòng)過濾用戶輸入的首尾空白字符demo
8.4 在組件上使用 v-model
閱讀指南 自定義輸入組件
9. 組件基礎(chǔ)
Vue 組件的示例demo
組件的復(fù)用
組件進(jìn)行任意次數(shù)的復(fù)用,每用一次組件,就會(huì)有一個(gè)它的新實(shí)例被創(chuàng)建。demo 注意:組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝。
組件的組織
應(yīng)用會(huì)以一棵嵌套的組件樹的形式來組織。組件使用前必須先注冊(cè)以便Vue能夠識(shí)別。注冊(cè)分為全局注冊(cè)demo和局部注冊(cè)
通過 Prop 向子組件傳遞數(shù)據(jù)demo 博文的例子
單個(gè)根元素 每個(gè)組件必須只有一個(gè)根元素
通過事件向父級(jí)組件發(fā)送消息
調(diào)用內(nèi)建的 $emit
方法并傳入事件的名字,來向父級(jí)組件觸發(fā)一個(gè)事件demo
使用事件拋出一個(gè)值 使用 $emit
的第二個(gè)參數(shù)來提供這個(gè)值,父級(jí)組件監(jiān)聽時(shí)通過$event訪問這個(gè)值demo,如果這個(gè)事件處理函數(shù)是一個(gè)方法,這個(gè)值將會(huì)作為第一個(gè)參數(shù)傳入這個(gè)方法demo
組件上使用 v-model demo
通過插槽分發(fā)內(nèi)容 在需要的地方加入插槽slot demo
動(dòng)態(tài)組件
在不同組件之間進(jìn)行動(dòng)態(tài)切換是非常有用的,比如在一個(gè)多標(biāo)簽的界面里demo
解析 DOM 模板時(shí)的注意事項(xiàng)