VUE2.0官方文檔
基礎部分:
1.VUE簡介
Vue是一個基於MVVM的框架,其中M代表數據處理層,V代表視圖層即我們在Vue組件中的html部分,VM即M和V的結合層,處理M層相應的邏輯數據,在V層實現渲染。Vue讓我們把精力更多的放在VM層上,即更多的關注業務邏輯,把DOM操作交給系統。
1)聲明式渲染:在vue實例對象中進行數據聲明,在V層響應式的進行DOM渲染。
2)條件與循環:v-if、v-for
3)處理用戶輸入:v-model
4)構建組件化應用:在大型應用中將應用程序划分為小型、獨立和可復用的組件,使開發更易管理
vue自定義組件和Web組件規范中自定義元素的關系:
Vue組件語法部分參考了Web組件規范,有幾個關鍵差別:
a)Web Components 規范未被所有瀏覽器原生實現,但是Vue組件被所有瀏覽器支持,且Vue組件可以包裝於原生自定義元素之內。
b)Vue組件提供了純自定義元素所不具備的一些重要功能,最突出的是跨組件數據流、自定義事件通信以及構建工具集成。
2.Vue實例
1)Vue實例創建:一個Vue應用由一個通過new Vue 創建的根Vue實例,以及可選的嵌套的、可復用的組件數組成。所有的Vue組件都是Vue實例,並且接受相同的選項對象(一些根實例特有的選項除外)。
2)Vue實例中允許在data對象中添加屬性,且這些屬性是響應式的。Vue還有一些有用的屬性和方法,以$為前綴
3)實例生命周期鈎子:
3.模板語法:
1)插值
a.文本插值:{}
b.解析HTML:v-html,會將數據解析為HTML代碼渲染,但是不能使用v-html來復合局部模板。(站點上動態渲染的任意 HTML 可能會非常危險,因為它很容易導致 XSS攻擊。請只對可信內容使用 HTML 插值,絕不要對用戶提供的內容使用插值)
c.綁定屬性:v-bind
d.可以使用JS表達式:每個綁定只能包含單個表達式。(模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 Math
和 Date
。你不應該在模板表達式中試圖訪問用戶定義的全局變量)
2)指令
a)指令的職責:當表達式的值改變時,將其產生的連帶影響,響應式地作用於 DOM
b)參數:一些指令能夠接受一些參數,在指令名稱之后用冒號表示(如:v-bind:href=“url”)
c)動態參數:從 2.6.0 開始,可以用方括號括起來的 JavaScript 表達式作為一個指令的參數
<a v-bind:[attributeName]="url"> ... </a>
(注:attributeName為null是可以用於顯示的去除屬性的綁定,且attributeName中不能包含引號、空格,大寫會被轉換成小寫)
d)修飾符:以半角句號 .
指明的特殊后綴,用於指出一個指令應該以特殊方式綁定。
例如,.prevent
修飾符告訴 v-on
指令對於觸發的事件調用 event.preventDefault()
:
<form v-on:submit.prevent="onSubmit">...</form>
e)縮寫:v-bind: =》 :
v-on:=> @
4.計算屬性(computed)和偵聽器(watch)
模板中表達式非常便利,但是它設計的初衷是用於簡單運算,而不是處理復雜邏輯。在處理復雜邏輯是我們使用計算屬性。
1)計算屬性(computed):
計算屬性和事件綁定的區別:計算屬性存在緩存,只有當它的依賴發生變化時才會重新執行,但是事件綁定在每次訪問都是會重新執行的。(這同時意味着如果計算屬性中不存在依賴,那么計算屬性的值將永遠不變。)
getter:(默認只有getter),計算屬性獲取值
setter:根據計算屬性反過來去改變其依賴的值
2)偵聽器 watch:當需要在數據變化時執行異步或開銷較大的操作時,使用偵聽器更好。
5.Class與Style綁定
針對class列表和內聯樣式,v-bind做了專門的增強,值除了可以是字符串外,還可以是對象或者數組。
v-bind:class、v-bind:style : 通常有兩種使用方式 -- 對象語法和數組語法
對象語法:
1)<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }" ></div>
data:{
isActive:true,
hasError:false
}
2)<div v-bind:class="classObject"></div>
data: {
classObject: { active: true, 'text-danger': false } }
3)
同時可以使用計算屬性改改變classObject值
<div v-bind:class="classObject"></div>
data: { isActive: true, error: null },
computed: {
classObject: function () {
return { active: this.isActive && !this.error, 'text-danger': this.error && this.error.type === 'fatal' }
}
}
數組語法:
1)<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active', errorClass: 'text-danger' }
2)可以使用三元表達式:
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
3)在數組語法中也可以使用對象語法
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
v-bind:style 使用需要添加瀏覽器前綴的css屬性時,vue會自動添加。
從2.3.0 開始,v-bind:style 綁定的屬性中可以提供一個包含多個值的數組,常用於提供多個帶前綴的值,如:<div :style="{ display: ['-webkit-box', '-ms-flexbox', 'flex'] }"></div>,這樣寫只會渲染數組中最后一個被瀏覽器支持的值。
6.條件渲染
1)v-if
v-if-else(2.1.0新增)
v-else
用key 解決元素復用:vue會盡可能高效地渲染元素,通常會復用已有元素而不是從頭渲染,這常常會造成元素不更新的情況,如果想避免這種問題,可以用key解決
2)v-show
v-show不同於v-if,v-show的元素始終會被渲染並保留在DOM中,它操作的是元素的display屬性,同時v-show不支持<template>元素。
3)v-if 和 v-show 比較
v-if
是“真正”的條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建。
v-if
也是惰性的:如果在初始渲染時條件為假,則什么也不做——直到條件第一次變為真時,才會開始渲染條件塊。
相比之下,v-show
就簡單得多——不管初始條件是什么,元素總是會被渲染,並且只是簡單地基於 CSS 進行切換。
一般來說,v-if
有更高的切換開銷,而 v-show
有更高的初始渲染開銷。因此,如果需要非常頻繁地切換,則使用 v-show
較好;如果在運行時條件很少改變,則使用 v-if
較好。
7.列表渲染
1)v-for
數組遍歷:v-for = “(item,index)in items”
對象遍歷:v-for ="(value,key,index)in object"
key:v-for情況下盡量使用綁定key屬性
2)數組更新檢測
a)變異方法(會改變數組的方法):push()、pop()、shift()、unshift()、splice()、sort()、reverse(),這些方法都會觸發數組的更新
b)由於JavaScript的顯示,vue不能檢測一下變動的數組
-
- 當你利用索引直接設置一個項時,例如:
vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如:
vm.items.length = newLength
- 當你利用索引直接設置一個項時,例如:
但是有解決方法:
vm.items[indexOfItem] = newValue 的解決方法 => 1) Vue.set(vm.items, indexOfItem, newValue)
2) Vm.items.splice(indexOfItem, 1, newValue)
vm.items.length = newLength 的解決方法 => vm.items.splice(newLength)
這些方法就會觸發更新了
3)對象的更新檢測
a) vue不能檢測對象屬性的添加和刪除,對於已經創建的實例,vue不能動態添加跟級別的相應,但是可以使用 Vue.set(object, key, value)
方法向嵌套對象添加響應式屬性。列如:
var vm = new Vue({
data: { userProfile: {
name: 'Anika'
}
}
})
Vue.set(vm.userProfile, 'age', 27)
b) 在為嵌套對象添加多個新屬性時,應該這樣做:
vm.userProfile = Object.assign({}, vm.userProfile, {
age: 27,
favoriteColor: 'Vue Green'
})
4)一段取值范圍的v-for
<div> <span v-for="n in 10">{{ n }} </span> </div> 結果:1 2 3 4 5 6 7 8 9 10
5)v-for 和 v -if 同時使用:v-for 的優先級高於 v-if
6)組件中使用v-for:數據不會自動傳遞到組件中,因為組件有自己的作用域,為了把迭代數據傳到組件里,我們需要使用props
8.事件處理
1)監聽事件 :v-on
2)事件處理:通常配合methods使用
3)事件修飾符:.stop .prevent .capture .self .once .passive
4)按鍵修飾符(按鍵碼:盡量不適用按鍵碼)
5)系統修飾鍵:.ctrl .alt .shift .meta .exact(精准修飾符)
6)鼠標修飾符: .left .right .middle
在HTML中設置事件監聽的原因(這樣能做是不是違背了我們希望把關注點放在VM層的原則,沒有),因為vue都把這些(事件處理方法和表達式)綁定到了VM層了。同時使用v-on有如下好處:
-
掃一眼 HTML 模板便能輕松定位在 JavaScript 代碼里對應的方法。
-
因為你無須在 JavaScript 里手動綁定事件,你的 ViewModel 代碼可以是非常純粹的邏輯,和 DOM 完全解耦,更易於測試。
-
當一個 ViewModel 被銷毀時,所有的事件處理器都會自動被刪除。你無須擔心如何清理它們
9.表單輸入綁定
1)基本用法:v-model,在相應元素上創建雙向數據綁定,它會根據控件類型自動選取正確的方法來更新元素。
處理的元素包括:文本、多行文本、復選框(單個復選框綁定布爾值,多個復選框綁定到數組)、單選按鈕、選擇框(單選框和復選框)
2)修飾符:.lazy .number .trim
10.組件基礎
1)組件是可復用的Vue實例,所以與new Vue 接受相同的選項(除了根實例特有的選項外)。
2)組件復用:組件是可以復用的,但是其中維護的數據,復用的組件都會有自己相應獨立的數據,因為每用一次組件,就會有一個新實例被創建。(組件的data選項必須是一個函數,這樣才能保障給每個實例都返回一個對象的獨立拷貝)
3)通過Prop向子組件傳遞數據:通過在子組件上使用props選項為組件綁定相應的自定義屬性,在調用子組件時設置相應屬性的值就達到了向子組件傳遞數據的效果。
4)監聽子組件事件:父組件可以通過子組件上的v-on監聽子組件的任意事件,子組件首先通過$emit 觸發自身綁定的事件,這時父組件就會接收到這個事件。
a.子組件可以通過$emit 來拋出一個值的
b.子組件上使用v-model:
對於正常的元素使用v-model:
但是在組件上使用v-model:
為了讓其正常工作,組件內的<input>需要做相應的處理:
5)通過插槽分發內容(后面詳述)
6)動態組件(后面詳述)
7)在HTML中有些元素其內容元素內容或者其所屬元素都是有規定的,如<table>中應該包含<tr>,但是如果在<table>中使用模板,會導致渲染出錯。可以使用is 特性解決:
但是我們通過以下來源使用模板的話,就不會出現這樣的問題了:
深入了解組件:
1.組件注冊
1)組件名:組件名推薦使用短橫線分割命名
2)全局注冊:Vue.component(),全局注冊的組件可以應用於其注冊之后的任何新創建的Vue跟實例及其子組件中
3)局部注冊:
局部注冊的組件在子組件之間不可使用。
4)模塊系統
a.在模塊系統中局部注冊:
b.基礎組件的自動化全局注冊(對於基礎組件,我們應該自動化的全局部署他,而不是每個組件中局部部署)
全局導入基礎組件的實例代碼:
2.Prop
1)prop名如果使用駝峰命名法,在調用使用時需要使用短橫線分割命名法。
2)Prop類型:通常使用對象的形式列出prop,指定值類型
3)傳值:可以給prop設置的屬性傳入靜態或動態的值,且可以傳入任何類型的值
4)單向數據流:prop都是單向的,這樣會防止從子組件意外改變父級組件的狀態(對於對象和數組是通過引用傳入的,會改變)
5)Prop驗證:在設置props值時可以提供一個帶有驗證需求的對象,這樣如果使用時一個類型不一致,Vue會在控制台中發出警告。(注意prop會在一個組件實例創建之前進行驗證,所以實例的屬性(如data、computed等)在default或validator函數中不可用)。
6)非Prop特性:在很多情況下我們並不知道一個組件將來會傳入什么樣的特性值,所以組件是可以接收任意特性的,而這些特性也會被添加到組件的根元素上。
a.對於絕大多數特性來說,從外部提供給組件的值會替換掉組件內容原來設置好的值,但是對於class和style,值會合並。
b.在開發基礎組件時,我們很多時候不需要其上層集成過來的元素特性,我們可以給組件設置 inheritAttrs :false 來禁用特性繼承。(inheritAttrs:false 不會影響style 和 class 的綁定)
3.自定義事件
1)事件名:事件名是完全匹配的,所以不像組件名和prop名一樣,camelCase的名字不會映射到kebab-case 名字上。同時v-on綁定的事件會自動轉換為全小寫。
因此,我們推薦所有命名使用kebab-case 命名
2)自定義組件使用v-model:v-model會默認利用名為value的prop和名為 input 的事件,但是對於像單選框這樣的輸入控件會對value有不同的目的,使用model選項可以用來避免這樣的沖突。
3)將原生事件綁定到組件
4).sync 修飾符:默認情況下組件通信是單向的,如果我們希望子組件改變父組件,我們一般通過子組件傳遞事件來實現。
為了方便起見,Vue為這種方式提供了一種縮寫,即.sync 修飾符
4.插槽
1)插槽的內容:帶有插槽的組件在使用時可以向其中填充任何模板代碼和HTML
2)插槽的作用域:父級模板里的內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。
3)后備內容:插槽在沒有提供內容時默認顯示的內容
4)具名插槽:插槽可以綁定一個name 屬性,在使用時,<template v-solt:name 屬性值> 即可用<temlate> 標簽之間的內容替換掉插槽
5)作用域插槽:插槽只可以訪問在定義時所在的vue實例中的數據,在模板中定義插槽時有時插槽會訪問子組件中的數據,但在使用時,直接使用時是調用不了子組件中的數據的。這時候在插槽定義中使用插槽prop,在調用時<template> 上用v-slot 定義一個插槽prop的別名,利用別名就可以在使用時訪問到相應數據。
解構插槽prop:插槽別名可以直接使用ES5解構,如{user}這樣的形式。
插槽名可以使用動態的:v-slot:[dynamicSlotName]
v-slot縮寫:#
5.動態組件&異步組件
1)動態組件保持原來的狀態,不重新渲染:使用<keep-alive>
2)異步組件:??沒看懂
6.處理邊界情況(在某些情況下,我們需要對vue的規則做一些特殊調整,不過這些調整都是有優勢和劣勢的,如何取舍使用根據具體情況使用)
1)訪問元素和組件(在大多數情況下我們最好不要手動操作一個組件實例內部或者DOM,但是在某些情況下是必要的)
a)訪問根實例:$root (推薦使用Vuex來管理應用的狀態)
b)訪問父級組件實例:$parent ($parent 容易是應用造成混亂,在向任意深層次組件提供信息是推薦使用依賴注入)
c)訪問子組件:在子組件定義時可以添加一個ref屬性,后期可以通過$.refs.屬性值來訪問到這個子組件($refs 只在組件渲染完成之后生效,且並不是響應式的)
d)依賴注入:可以在父組件中使用provide屬性定義響應的數據或方法,后代組件使用reject就可以接受的響應的數據或方法。(但是依賴注入會是程序變得耦合 ,且所提供的屬性時非響應式的,所以還是推薦使用Vuex )
2)程序化的事件偵聽器(不經常使用)
3)循環引用
組件之間可以循環引用,但要注意設置一個點 ,結束這種循環關系,防止死循環。