一斧吐、全局API
何為全局API宵睦? 通俗的說就是在構(gòu)造器之外,Vue提供的一些API函數(shù)杜耙,可以使我們定義新的功能烟勋。
自定義指令 Vue.directive
通過例子來看:定義一個(gè)指令规求,讓num的顏色變成紅色筐付。
<div id="app">
<div v-cui="color">{{ num }}</div>
<button @click = "add">增加</button>
</div>
傳入一個(gè)函數(shù)
Vue.directive('cui', function(el, binding, vnode){
//console.log(el)//綁定了自定義指令‘cui’的節(jié)點(diǎn)
//console.log(binding)//是一個(gè)對(duì)象,包含指令的很多信息阻肿。
//console.log(vnode)//編譯生成的虛擬節(jié)點(diǎn)
el.style.color = binding.value;
})
var app = new Vue({
el: "#app",
data: {
num: 10,
color: 'red'
},
methods: {
add(){
this.num++
}
}
})
傳入一個(gè)對(duì)象瓦戚,分別是五個(gè)生命周期鉤子函數(shù)
<div id="app" v-cloak>
<div v-cui="color">{{ num }}</div>
<button @click = "add">增加</button>
</div>
<button onclick = 'unbind()'>解綁</button>
//五個(gè)生命周期鉤子函數(shù),我們可以在不同周期進(jìn)行相應(yīng)的操作
Vue.directive('cui', {
bind: function () {
console.log('第一次被綁定')
},
inserted: function(){
console.log('被綁定元素插入到父節(jié)點(diǎn)')
},
update: function(){
console.log('組件更新')
},
componentUpdated: function(){
console.log('組件更新完成')
},
unbind: function(){
console.log('組件解綁')
}
})
//解綁函數(shù)需要定義在構(gòu)造器之外
function unbind(){
app.$destroy()
}
var app = new Vue({
el: "#app",
data: {
num: 10,
color: 'red'
},
methods: {
add(){
this.num++
// this.color = "green"
}
}
})
- bind:只調(diào)用一次丛塌,指令第一次綁定到元素時(shí)調(diào)用较解,用這個(gè)鉤子函數(shù)可以定義一個(gè)執(zhí)行一次的初始化操作。
- inserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用赴邻。
- update:被綁定于元素所在的模板更新時(shí)調(diào)用印衔,而無論綁定值是否變化。通過比較更新前后的綁定值姥敛,可以忽略不必要的模板更新奸焙。
- componentUpdated:被綁定元素所在模板完成一次更新周期時(shí)調(diào)用。
- unbind:只調(diào)用一次彤敛,指令與元素解綁時(shí)調(diào)用与帆。
二、extend擴(kuò)張實(shí)例構(gòu)造器
<div id="app">
<nav-bar id="nav"></nav-bar>
</div>
//擴(kuò)張構(gòu)造器
var NavBar = Vue.extend({
template: "<div><ul><a :href='url'><li>{{msg1}}</li></a><li>{{msg2}}</li></ul></div>",
data(){
return {
msg1: '首頁',
url: 'https://baidu.com',
msg2: '關(guān)于我'
}
}
})
//創(chuàng)建自定義構(gòu)造器實(shí)例墨榄,并掛載
new NavBar().$mount('#nav')//這里可以是id玄糟,類名,標(biāo)簽名
效果:
三袄秩、Vue.set
Vue.set的作用是在構(gòu)造器外部操作構(gòu)造器內(nèi)部的數(shù)據(jù)阵翎、屬性或方法。比如播揪,在Vue構(gòu)造器內(nèi)部定義一個(gè)數(shù)num為10贮喧,在外部定義一個(gè)方法改變num的值筒狠。
<div>{{ num }}</div>
//引用構(gòu)造器外部數(shù)據(jù)
var datas = {
num: 10,
stars: ['柳巖', '劉亦菲', '劉詩詩']
}
//三種方式改變num的值
function add() {
//1猪狈、 直接操作外部數(shù)據(jù)
datas.num ++
//2、 用Vue對(duì)象的方式添加
app.num ++
//3辩恼、 用Vue.set的方式改變
Vue.set(datas, 'num', 20)
}
var app = new Vue({
el: "#app",
data: datas,
methods: {
add(){
console.log(this.stars)
this.stars[1] = '高圓圓'
}
}
})
這時(shí)候你可能會(huì)產(chǎn)生疑問雇庙,為什么要用這么復(fù)雜的方式去改變num的值,當(dāng)然了灶伊,單純的去改變數(shù)的值疆前,自然是沒必要這么做的,不妨看下面的例子聘萨,我們通過問題來引入:
假設(shè)我們通過一個(gè)事件去改變數(shù)組中的某個(gè)元素竹椒,你會(huì)發(fā)現(xiàn),值改變了米辐,但是并沒有更新視圖胸完。
<div id="#app">
<ul>
<li v-for = "star in stars">{{ star }}</li>
</ul>
<button @click = 'add()'>add</button>
</div>
通過點(diǎn)擊事件书释,將‘劉亦菲’改成‘高圓圓’
//引用構(gòu)造器外部數(shù)據(jù)
var app = new Vue({
el: "#app",
data: {
stars: ['柳巖', '劉亦菲', '劉詩詩']
},
methods: {
add(){
console.log(this.stars)
this.stars[1] = '高圓圓'
}
}
})
結(jié)果是數(shù)組的值變了,但是并沒有更新視圖赊窥。
這種問題是由于Javascript的限制爆惧,Vue不能自動(dòng)檢測(cè)以下方式變動(dòng)的數(shù)組。
- 當(dāng)你利用索引直接設(shè)置一個(gè)項(xiàng)時(shí)锨能,vue不會(huì)為我們自動(dòng)更新扯再。
但是,當(dāng)我們?cè)谝粋€(gè)事件中同時(shí)改變一個(gè)數(shù)的值和數(shù)組中的某個(gè)元素址遇,那么此時(shí)數(shù)組中的值也會(huì)相應(yīng)的改變熄阻。原因是虛擬DOM,當(dāng)我們通過事件改變num的值時(shí)倔约,會(huì)改變虛擬DOM饺律,觸發(fā)視圖的更新。如下:
data: {
num: 10,
stars: ['柳巖', '劉亦菲', '劉詩詩']
},
methods: {
add(){
this.num ++
this.stars[1] = '高圓圓'
console.log(this.stars)
//this.stars.push('趙麗穎')
}
}
但是我們?cè)趯?shí)際項(xiàng)目開發(fā)中跺株,只需要改變數(shù)組中的某個(gè)元素复濒,那么就需要Vue.set()了。
var datas = {
stars: ['柳巖', '劉亦菲', '劉詩詩']
}
function add() {
//改變數(shù)組中的元素
Vue.set(app.stars, 1, '高圓圓')
}
var app = new Vue({
el: "#app",
data: datas
})
也可以在構(gòu)造器實(shí)例中通過Vue.set()去改變乒省,效果也是一樣的巧颈。
<ul>
<li v-for = "star in stars">{{ star }}</li>
</ul>
<button @click = 'add()'>add</button>
var app = new Vue({
el: "#app",
// data: datas,
data: {
stars: ['柳巖', '劉亦菲', '劉詩詩']
},
methods: {
add(){
// this.stars[1] = '高圓圓'
// console.log(this.stars)
Vue.set(app.stars, 1, "高圓圓")
}
}
})
四、生命周期
何為生命周期袖扛?對(duì)一個(gè)生物來說砸泛,生命周期便是從出生到死亡的過程,那中間一定還有很多的時(shí)間點(diǎn)蛆封,比如唇礁,少年、青年惨篱、中年盏筐、老年等,不同階段可以做不同的事情砸讳。Vue中的生命周期也是如此琢融,它包括從Vue實(shí)例的創(chuàng)建到銷毀,以及中間經(jīng)歷的不同時(shí)間點(diǎn)簿寂。
Vue所有的生命周期鉤子自動(dòng)綁定在this上下文到實(shí)例中漾抬,因此可以訪問數(shù)據(jù),并對(duì)屬性和方法進(jìn)行運(yùn)算常遂。同時(shí)意味著不能使用箭頭函數(shù)來定義一個(gè)生命周期方法纳令。因?yàn)榧^函數(shù)綁定了父上下文,因此this與你期待的Vue實(shí)例不同。
還是通過代碼來看吧:
<div id="app">
<div>{{ num }}</div>
<button @click = "add">add</button>
<button onclick="app.$destroy()">銷毀</button>
</div>
var app = new Vue({
el: "#app",
data: {
num : 10
},
methods: {
add(){
this.num ++
}
},
// 實(shí)例初始化之后平绩,數(shù)據(jù)觀測(cè)(data observer) 和 event/watcher 事件配置之前被調(diào)用
beforeCreate:function(){
console.log('1-beforeCreate 實(shí)例初始化之后');
},
created:function(){
console.log('2-created 創(chuàng)建完成');
},
beforeMount:function(){
console.log('3-beforeMount 掛載之前');
},
mounted:function(){
console.log('4-mounted 被創(chuàng)建');
},
beforeUpdate:function(){
console.log('5-beforeUpdate 數(shù)據(jù)更新前');
},
updated:function(){
console.log('6-updated 被更新后');
},
activated:function(){
console.log('7-activated');
},
deactivated:function(){
console.log('8-deactivated');
},
beforeDestroy:function(){
console.log('9-beforeDestroy 銷毀之前');
},
destroyed:function(){
console.log('10-destroyed 銷毀之后')
}
})
初次打開頁面
點(diǎn)擊按鈕坤按,更新組件
點(diǎn)擊銷毀按鈕
Vue組件的生命周期這篇文章對(duì)生命周期鉤子的解釋還是比較通俗的。
1馒过、beforeCreate
在實(shí)例初始化之后臭脓,數(shù)據(jù)觀測(cè)和event/watcher時(shí)間配置之前被調(diào)用。
2腹忽、created
實(shí)例已經(jīng)創(chuàng)建完成之后被調(diào)用来累。在這一步,實(shí)例已經(jīng)完成以下的配置:數(shù)據(jù)觀測(cè)窘奏,屬性和方法的運(yùn)算嘹锁,watch/event事件回調(diào)。然而着裹,掛載階段還沒開始领猾,$el屬性目前不可見。
3骇扇、beforeMount
在掛載開始之前被調(diào)用:相關(guān)的render函數(shù)首次被調(diào)用摔竿。
該鉤子在服務(wù)器端渲染期間不被調(diào)用。
4少孝、mounted
el被新創(chuàng)建的vm.$el替換继低,并掛在到實(shí)例上去之后調(diào)用該鉤子函數(shù)。如果root實(shí)例掛載了一個(gè)文檔內(nèi)元素稍走,當(dāng)mounted被調(diào)用時(shí)vm.$el也在文檔內(nèi)袁翁。
該鉤子在服務(wù)端渲染期間不被調(diào)用。
5婿脸、beforeUpdate
數(shù)據(jù)更新時(shí)調(diào)用粱胜,發(fā)生在虛擬DOM重新渲染和打補(bǔ)丁之前。
你可以在這個(gè)鉤子中進(jìn)一步第更改狀態(tài)狐树,這不會(huì)觸發(fā)附加的重渲染過程焙压。
該鉤子在服務(wù)端渲染期間不被調(diào)用。
6褪迟、updated
由于數(shù)據(jù)更改導(dǎo)致的虛擬DOM重新渲染和打補(bǔ)丁冗恨,在這之后會(huì)調(diào)用該鉤子答憔。
當(dāng)這個(gè)鉤子被調(diào)用時(shí)味赃,組件DOM已經(jīng)更新,所以你現(xiàn)在可以執(zhí)行依賴于DOM的操作虐拓。然而在大多數(shù)情況下心俗,你應(yīng)該避免在此期間更改狀態(tài),因?yàn)檫@可能會(huì)導(dǎo)致更新無限循環(huán)。
該鉤子在服務(wù)端渲染期間不被調(diào)用城榛。
7揪利、activated
keep-alive組件激活時(shí)調(diào)用。
該鉤子在服務(wù)器端渲染期間不被調(diào)用狠持。
8疟位、deactivated
keep-alive組件停用時(shí)調(diào)用。
該鉤子在服務(wù)端渲染期間不被調(diào)用喘垂。
9甜刻、beforeDestroy 【類似于React生命周期的componentWillUnmount】
實(shí)例銷毀之間調(diào)用。在這一步正勒,實(shí)例仍然完全可用得院。
該鉤子在服務(wù)端渲染期間不被調(diào)用。
10章贞、destroyed
Vue實(shí)例銷毀后調(diào)用祥绞。調(diào)用后,Vue實(shí)例指示的所有東西都會(huì)解綁定鸭限,所有的事件監(jiān)聽器會(huì)被移除蜕径,所有的子實(shí)例也會(huì)被銷毀。
該鉤子在服務(wù)端渲染不會(huì)被調(diào)用败京。