在前端開(kāi)發(fā)中,Vue.js常被用來(lái)開(kāi)發(fā)響應(yīng)式的頁(yè)面,通過(guò)Vue可以將頁(yè)面響應(yīng)式綁定到數(shù)據(jù)上,在數(shù)據(jù)變化時(shí)自動(dòng)更新頁(yè)面。Vue非常方便易用,并且具有高度的可擴(kuò)展性。但是在使用Vue時(shí),我們需要注意一個(gè)細(xì)節(jié)問(wèn)題:Vue無(wú)法監(jiān)聽(tīng)數(shù)組。
var vue = new Vue({
data: {
list: []
},
watch: {
list: function (newList, oldList) {
// 檢測(cè)到了list數(shù)組的變化
}
}
})
vue.list.push(1) // 無(wú)法檢測(cè)到list數(shù)組的變化
從上面的代碼片段中可以看到,當(dāng)我們創(chuàng)建了一個(gè)Vue實(shí)例后,在data中定義了一個(gè)數(shù)組list。在watch中監(jiān)聽(tīng)list屬性值的變化。然而,當(dāng)我們往list中push一些數(shù)據(jù)時(shí),系統(tǒng)無(wú)法監(jiān)聽(tīng)到list的變化。雖然數(shù)據(jù)添加成功,但是watch監(jiān)聽(tīng)不到。這是因?yàn)閂ue無(wú)法監(jiān)聽(tīng)到數(shù)組變化。
// 將list數(shù)組封裝成一個(gè)對(duì)象,并增加一個(gè)length屬性
var vue = new Vue({
data: {
listWrap: {
list: [],
length: 0
}
},
watch: {
listWrap: function (newVal, oldVal) {
// 檢測(cè)到了listWrap對(duì)象的變化
// 同時(shí)可以通過(guò)listWrap.length屬性判斷數(shù)組長(zhǎng)度變化
}
}
})
vue.listWrap.list.push(1) // 可以檢測(cè)到listWrap的變化
那么,如何解決Vue無(wú)法監(jiān)聽(tīng)數(shù)組的問(wèn)題呢?解決方案是封裝數(shù)組成一個(gè)對(duì)象,并增加一個(gè)length屬性,通過(guò)監(jiān)聽(tīng)對(duì)象的變化來(lái)判斷數(shù)組的改變。如上面代碼所示,我們將list數(shù)組封裝成了一個(gè)listWrap對(duì)象,并增加了一個(gè)length屬性。當(dāng)我們往list中添加數(shù)據(jù)時(shí),雖然無(wú)法監(jiān)聽(tīng)到list數(shù)組的變化,但是可以監(jiān)聽(tīng)到listWrap對(duì)象的變化,同時(shí)通過(guò)listWrap.length屬性判斷數(shù)組長(zhǎng)度變化。
在Vue中無(wú)法監(jiān)聽(tīng)數(shù)組的本質(zhì)問(wèn)題是:Vue通過(guò)Object.defineProperty()來(lái)實(shí)現(xiàn)數(shù)據(jù)的響應(yīng)式,而Object.defineProperty()方法只能監(jiān)聽(tīng)普通對(duì)象屬性的變化,無(wú)法監(jiān)聽(tīng)數(shù)組的變化。針對(duì)這個(gè)問(wèn)題,Vue已經(jīng)提供了一些解決辦法,比如使用vm.$set()方法或數(shù)組方法vm.list.push()、vm.list.pop()、vm.list.shift()、vm.list.unshift()、vm.list.splice()、vm.list.sort()、vm.list.reverse()來(lái)改變數(shù)組,這樣我們就可以讓Vue響應(yīng)式地監(jiān)聽(tīng)到數(shù)組的變化了。但是這些方法的使用場(chǎng)景比較有限,不適合所有情況的數(shù)組操作,因此我們還是需要封裝數(shù)組成對(duì)象的方式來(lái)解決Vue無(wú)法監(jiān)聽(tīng)數(shù)組的問(wèn)題。
綜上所述,Vue無(wú)法監(jiān)聽(tīng)數(shù)組的問(wèn)題是一個(gè)常見(jiàn)的坑點(diǎn),需要注意。如果遇到無(wú)法監(jiān)聽(tīng)數(shù)組的情況,我們可以將數(shù)組封裝成一個(gè)對(duì)象,并增加一個(gè)length屬性來(lái)解決。當(dāng)然,在Vue的特殊方法中改變數(shù)組的操作也可以被Vue監(jiān)聽(tīng)到,但是并不適合所有場(chǎng)景。