Vue 實例
在文檔中經(jīng)常會使用 vm 這個變量名表示 Vue 實例,在實例化 Vue 時,需要傳入一個選項對象,它可以包含數(shù)據(jù)(data)、模板(template)、掛載元素(el)、方法(methods)、生命周期鉤子(lifecyclehook)等選項。
Vue 實例化的選項
需要注意的是含 this 的函數(shù)大多不要使用箭頭函數(shù),因為我們期望 this 指向 Vue 實例。
data
Vue 實例的數(shù)據(jù)都保存在 data 對象中,Vue 將會遞歸將 data 的屬性轉(zhuǎn)換為 getter/setter,從而讓 data 的屬性能夠響應(yīng)數(shù)據(jù)變化。
1
2
3
4
5
6
7vardata = { a: 1 }
// 直接創(chuàng)建一個實例
varvm =newVue({
data: data
})
vm.a// -> 1
vm.$data === data// -> true
這樣數(shù)據(jù)就綁定在 HTML 中,Vue 框架監(jiān)視 data 的數(shù)據(jù)變化,自動更新 HTML 內(nèi)容。
computed
計算屬性將被混入到 Vue 實例中。所有 getter 和 setter 的 this 上下文自動地綁定為 Vue
實例。
22varvm =newVue({
data: { a: 1 },
computed: {
// 僅讀取,值只須為函數(shù)
aDouble:function() {
returnthis.a * 2
},
// 讀取和設(shè)置
aPlus: {
get:function() {
returnthis.a + 1
},
set:function(v) {
this.a = v - 1
}
}
}
})
vm.aPlus// -> 2
vm.aPlus = 3
vm.a// -> 2
vm.aDouble// -> 4
這里可以省略setter,如果省略了setter,那么值就可以是普通函數(shù),但是必須有返回值。
methods
methods 將被混入到 Vue 實例中。可以直接通過 VM 實例訪問這些方法,或者在指令表達式中使用。方法中的 this 自動綁定為 Vue 實例。
10varvm =newVue({
data: { a: 1 },
methods: {
plus:function() {
this.a++
}
}
})
vm.plus()
vm.a// 2
看下面這個例子,methods 和 computed 看起來可以做同樣的事情,單純看結(jié)果兩種方式確實是相同的。然而,不同的是計算屬性是基于它們的依賴進行緩存的。計算屬性只有在它的相關(guān)依賴發(fā)生改變時才會重新求值。這就意味著只要 message 還沒有發(fā)生改變,多次訪問 reversedMessage 計算屬性會立即返回之前的計算結(jié)果,而不必再次執(zhí)行函數(shù)。相比而言,只要發(fā)生重新渲染,method 調(diào)用總會執(zhí)行該函數(shù)。
13varvm =newVue({
el:'#example',
data: {
message:'Hello'
},
computed: {
// a computed getter
reversedMessage:function() {
// `this` points to the vm instance
returnthis.message.split('').reverse().join('')
}
}
})
watch
一個對象,鍵是需要觀察的表達式,值是對應(yīng)回調(diào)函數(shù)。值也可以是方法名,或者包含選項的對象。Vue實例將會在實例化時調(diào)用 $watch(),遍歷 watch 對象的每一個屬性。
19varvm =newVue({
data: {
a: 1,
b: 2,
c: 3
},
watch: {
// 監(jiān)控a變量變化的時候,自動執(zhí)行此函數(shù)
a:function(val, oldVal) {
console.log('new: %s, old: %s', val, oldVal)
},
// 深度 watcher
c: {
handler:function(val, oldVal) {/* ... */},
deep:true
}
}
})
vm.a = 2// -> new: 2, old: 1
Vue 實例的生命周期
Vue 實例有一個完整的生命周期,也就是從開始創(chuàng)建、初始化數(shù)據(jù)、編譯模板、掛載Dom→渲染、更新→渲染、卸載等一系列過程,我們稱這是 Vue 的生命周期。通俗說就是 Vue 實例從創(chuàng)建到銷毀的過程,就是生命周期。
在Vue的整個生命周期中,它提供了一些生命周期鉤子,給了我們執(zhí)行自定義邏輯的機會。
接下來我們用幾個例子來看看生命周期鉤子是怎么用的:
HTML結(jié)構(gòu):
{{ number }}
我們對 input 和 p 綁定了data 對象的 number 數(shù)據(jù),Vue 實例構(gòu)建如下:
6varapp =newVue({
el:'#app',
data: {
number: 1
}
})
在實例中分別在每個生命周期鉤子中 console.log('鉤子名稱',this.number) 我們發(fā)現(xiàn),第一次頁面加載時觸發(fā)了 beforeCreate, created, beforeMount, mounted 這幾個鉤子,data 數(shù)據(jù)在 created 中可獲取到。
再去 console.log('mounted: ', document.getElementsByTagName('p')[0]) ,DOM 渲染在 mounted 中已經(jīng)
完成。
我們再試著去更改 input 輸入框中的內(nèi)容,可以看到輸入框上方的數(shù)據(jù)同步發(fā)生改變,這就是數(shù)據(jù)綁定的效果,在更新數(shù)據(jù)時觸發(fā) beforeUpdate 和 updated 鉤子,且在 beforeUpdate 觸發(fā)時,數(shù)據(jù)已更新完畢。
而 destroy 僅在調(diào)用app.$destroy();時觸發(fā),對 vue 實例進行銷毀。銷毀完成后,我們再重新改變 number 的值,vue 不再對此動作進行響應(yīng)了。但是原先生成的dom元素還存在,可以這么理解,執(zhí)行了destroy操作,后續(xù)就不再受vue控制了。
Vue.nextTick
在下次 DOM 更新循環(huán)結(jié)束之后執(zhí)行延遲回調(diào)。在修改數(shù)據(jù)之后立即使用這個方法,獲取更新后的 DOM。
3Vue.nextTick(function() {
// DOM 更新了
})
官方還提供了一種寫法,vm.$nextTick,用 this 自動綁定到調(diào)用它的實例上
8created() {
setTimeout(() => {
this.number = 100
this.$nextTick(() => {
console.log('nextTick', document.getElementsByTagName('p')[0])
})
},100)
}
什么時候需要用的Vue.nextTick()
在 Vue 生命周期的 created() 鉤子函數(shù)進行的 DOM 操作一定要放在 Vue.nextTick() 的回調(diào)函數(shù)中。原因是什么呢,原因是在 created() 鉤子函數(shù)執(zhí)行的時候 DOM 其實并未進行任何渲染,而此時進行 DOM 操作無異于徒勞,所以此處一定要將 DOM 操作的 js 代碼放進 Vue.nextTick() 的回調(diào)函數(shù)中。與之對應(yīng)的就是 mounted 鉤子函數(shù),因為該鉤子函數(shù)執(zhí)行時所有的 DOM 掛載和渲染都已完成,此時在該鉤子函數(shù)中進行任何DOM操作都不會有問題 。
在數(shù)據(jù)變化后要執(zhí)行的某個操作,而這個操作需要使用隨數(shù)據(jù)改變而改變的 DOM 結(jié)構(gòu)的時候,這個操作都應(yīng)該放進 Vue.nextTick() 的回調(diào)函數(shù)中。
生命周期小結(jié)
生命周期鉤子的一些使用方法:
beforecreate : 可以在這加個loading事件,在加載實例時觸發(fā)
created : 初始化完成時的事件寫在這里,如在這結(jié)束loading事件,異步請求也適宜在這里調(diào)用
mounted : 掛載元素,獲取到DOM節(jié)點
updated : 如果對數(shù)據(jù)統(tǒng)一處理,在這里寫上相應(yīng)函數(shù)
beforeDestroy : 可以做一個確認停止事件的確認框
nextTick : 更新數(shù)據(jù)后立即操作dom
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
原文鏈接:https://segmentfault.com/a/1190000008771768