Vue踩坑之Vue?Watch方法不能監(jiān)聽到數(shù)組或?qū)ο笾档母淖冊斀?/h1>
更新時(shí)間:2022年04月01日 10:10:19 作者:星海拾遺
Vue 提供了一種更通用的方式來觀察和響應(yīng) Vue 實(shí)例上的數(shù)據(jù)變動(dòng):偵聽屬性,下面這篇文章主要給大家介紹了關(guān)于Vue踩坑之Vue?Watch方法不能監(jiān)聽到數(shù)組或?qū)ο笾档母淖兊南嚓P(guān)資料,需要的朋友可以參考下
前言
Vue不能監(jiān)聽到數(shù)組和對象值的變化其實(shí)和雙向綁定的原理有關(guān)。Vue雙向綁定原理是利用js中的Object.defineproperty重定義對象的GET和SET方法,而同時(shí)這種方法存在著缺陷。就是只能監(jiān)聽到對象內(nèi)已有的值。在監(jiān)聽對象中屬性變化的方法中中,無疑是 使用ES6的proxy更為優(yōu)越。
同時(shí)我對Vue中不能監(jiān)聽到數(shù)組對象變化也做了試驗(yàn)。代碼如下。
let vm = new Vue({
el: '#app',
data: {
message: 'wxs',
arr:[1,2,3],
obj:{
name:'wxs',
age:21
}
},
methods:{
change:function () {
this.message = 'vue'
this.arr[0]=100
this.obj.name='xxx'
}
},
watch:{
message:function (newValue,oldValue) {
console.log('message改變了')
},
arr:function (newValue,oldValue) {
console.log('arr改變了')
},
obj:function (newValue,oldValue) {
console.log('obj改變了')
}
},
template: `<div><div>{{message}}</div><div>{{arr[0]}}</div><div>{{obj.name}}</div><button @click="change()">改變!</button></div>`
})
很簡單的代碼,設(shè)置按鈕改變message,arr,obj的值,同時(shí)對這三個(gè)值的變化設(shè)置監(jiān)聽事件,測試結(jié)果如下。

視圖顯示三個(gè)值都發(fā)生了改變,但是Vue只監(jiān)聽到了第一個(gè)值的改變。
官方文檔給出如下解釋

對此Vue提供了解決辦法。
Vue不能監(jiān)聽到數(shù)組變化官方文檔中提出有以下有兩種情況。
一:利用索引直接改變arr的值 如我在button事件中寫的(arr[0]=1000)
解決方法 將this.arr[0]=1000改寫為Vue可以監(jiān)聽的形式 this.$set(this.arr,0,1000)
this.$set接受三個(gè)參數(shù),第一個(gè)是需要操作的數(shù)組對象,第二個(gè)是需要修改的數(shù)據(jù)的數(shù)組下標(biāo),第三個(gè)是修改后的值。
上圖看效果。
將修改arr值得方法修改如下
methods:{
change:function () {
this.message = 'vue'
this.$set(this.arr,0,100)
this.obj.name='xxx'
}
},

成功監(jiān)聽
二:直接修改數(shù)組的長度 如this.arr.length=3
來做個(gè)測試。我們用修改數(shù)組長度得方法刪除數(shù)組中的值,看看watch能不能監(jiān)聽的到。
methods:{
change:function () {
this.message = 'vue'
this.arr.length=0
this.obj.name='xxx'
}
},

結(jié)果,監(jiān)聽不到。
解決方法使用js中數(shù)組方法arr.splice操作數(shù)組達(dá)到修改長度的目的。

看看效果
methods:{
change:function () {
this.message = 'vue'
this.arr.splice(0,1)
this.obj.name='xxx'
}
},

我們將數(shù)組的第一個(gè)值刪除,此時(shí)數(shù)組的第二個(gè)值變成了arr[0],渲染到了頁面中,watch監(jiān)聽成功。
Vue中無法監(jiān)聽對象屬性的添加或者刪除
解決方法:this.$set(obj,name,‘xxx’)對對象進(jìn)行操作時(shí),set接受三個(gè)參數(shù),第一個(gè)為對象的名稱,第二個(gè)為對象的key值,第三個(gè)為key對應(yīng)的value值。
this.obj=Object.assign({},this.arr,{
age:21,
major:'soft'
})
這樣操作之后,便可以成功監(jiān)聽到數(shù)組和對象的變化了
methods:{
change:function () {
this.message = 'vue'
this.$set(this.arr,1,100)
this.$set(this.obj,'major','Vue')
}
},
控制臺(tái)輸出如下

那么問題來了,我改變的是對象的新值‘major’的值,請注意看我上面代碼中method方法中的設(shè)置obj的代碼。
此時(shí)Vue只是監(jiān)聽到了我改變了對象的新值。經(jīng)過我測試,我改變對象的舊值,比如name值。Vue依然監(jiān)聽不到對象的變化。此時(shí)Vue提出了深度監(jiān)聽的方法如下。

但是這種方法經(jīng)過我測試不能監(jiān)聽到對象新值的變化。
總結(jié)如下
總結(jié):如果操作對象是數(shù)組,改變數(shù)組的值用Vue的$set方法,改變數(shù)組的長度用數(shù)組的splice方法使數(shù)組變化變成可監(jiān)聽的。如果操作對象是對象。如果操作的屬性是對象內(nèi)已經(jīng)有的值,使用$watch,加上關(guān)鍵字deep深度監(jiān)聽對象,如果操作的屬性是對象內(nèi)沒有的新屬性。使用$set使對象變成可監(jiān)聽的!
到此這篇關(guān)于Vue踩坑之Vue Watch方法不能監(jiān)聽到數(shù)組或?qū)ο笾档母淖兊奈恼戮徒榻B到這了,更多相關(guān)Vue Watch方法不能監(jiān)聽數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
-
vue加載動(dòng)畫element ui V-loading屬性的踩坑記錄
這篇文章主要介紹了vue加載動(dòng)畫element ui V-loading屬性方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教 2023-06-06
-
Vue動(dòng)態(tài)創(chuàng)建注冊component的實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于Vue動(dòng)態(tài)創(chuàng)建注冊component的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
2019-06-06
-
Vue中使用JsonView來展示Json樹的實(shí)例代碼
這篇文章主要介紹了Vue之使用JsonView來展示Json樹的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下 2020-11-11
-
使用Element進(jìn)行前端開發(fā)的詳細(xì)圖文教程
眾所周知Element是一套Vue.js后臺(tái)組件庫,它能夠幫助你更輕松更快速地開發(fā)后臺(tái)項(xiàng)目,下面這篇文章主要給大家介紹了關(guān)于使用Element進(jìn)行前端開發(fā)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下 2022-11-11
-
基于Vue實(shí)現(xiàn)簡單的權(quán)限控制
這篇文章主要為大家學(xué)習(xí)介紹了如何基于Vue實(shí)現(xiàn)簡單的權(quán)限控制,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以了解一下 2023-07-07
最新評論
前言
Vue不能監(jiān)聽到數(shù)組和對象值的變化其實(shí)和雙向綁定的原理有關(guān)。Vue雙向綁定原理是利用js中的Object.defineproperty重定義對象的GET和SET方法,而同時(shí)這種方法存在著缺陷。就是只能監(jiān)聽到對象內(nèi)已有的值。在監(jiān)聽對象中屬性變化的方法中中,無疑是 使用ES6的proxy更為優(yōu)越。
同時(shí)我對Vue中不能監(jiān)聽到數(shù)組對象變化也做了試驗(yàn)。代碼如下。
let vm = new Vue({ el: '#app', data: { message: 'wxs', arr:[1,2,3], obj:{ name:'wxs', age:21 } }, methods:{ change:function () { this.message = 'vue' this.arr[0]=100 this.obj.name='xxx' } }, watch:{ message:function (newValue,oldValue) { console.log('message改變了') }, arr:function (newValue,oldValue) { console.log('arr改變了') }, obj:function (newValue,oldValue) { console.log('obj改變了') } }, template: `<div><div>{{message}}</div><div>{{arr[0]}}</div><div>{{obj.name}}</div><button @click="change()">改變!</button></div>` })
很簡單的代碼,設(shè)置按鈕改變message,arr,obj的值,同時(shí)對這三個(gè)值的變化設(shè)置監(jiān)聽事件,測試結(jié)果如下。
視圖顯示三個(gè)值都發(fā)生了改變,但是Vue只監(jiān)聽到了第一個(gè)值的改變。
官方文檔給出如下解釋
對此Vue提供了解決辦法。
Vue不能監(jiān)聽到數(shù)組變化官方文檔中提出有以下有兩種情況。
一:利用索引直接改變arr的值 如我在button事件中寫的(arr[0]=1000)
解決方法 將this.arr[0]=1000改寫為Vue可以監(jiān)聽的形式 this.$set(this.arr,0,1000)
this.$set接受三個(gè)參數(shù),第一個(gè)是需要操作的數(shù)組對象,第二個(gè)是需要修改的數(shù)據(jù)的數(shù)組下標(biāo),第三個(gè)是修改后的值。
上圖看效果。
將修改arr值得方法修改如下
methods:{ change:function () { this.message = 'vue' this.$set(this.arr,0,100) this.obj.name='xxx' } },
成功監(jiān)聽
二:直接修改數(shù)組的長度 如this.arr.length=3
來做個(gè)測試。我們用修改數(shù)組長度得方法刪除數(shù)組中的值,看看watch能不能監(jiān)聽的到。
methods:{ change:function () { this.message = 'vue' this.arr.length=0 this.obj.name='xxx' } },
結(jié)果,監(jiān)聽不到。
解決方法使用js中數(shù)組方法arr.splice操作數(shù)組達(dá)到修改長度的目的。
看看效果
methods:{ change:function () { this.message = 'vue' this.arr.splice(0,1) this.obj.name='xxx' } },
我們將數(shù)組的第一個(gè)值刪除,此時(shí)數(shù)組的第二個(gè)值變成了arr[0],渲染到了頁面中,watch監(jiān)聽成功。
Vue中無法監(jiān)聽對象屬性的添加或者刪除
解決方法:this.$set(obj,name,‘xxx’)對對象進(jìn)行操作時(shí),set接受三個(gè)參數(shù),第一個(gè)為對象的名稱,第二個(gè)為對象的key值,第三個(gè)為key對應(yīng)的value值。
this.obj=Object.assign({},this.arr,{ age:21, major:'soft' })
這樣操作之后,便可以成功監(jiān)聽到數(shù)組和對象的變化了
methods:{ change:function () { this.message = 'vue' this.$set(this.arr,1,100) this.$set(this.obj,'major','Vue') } },
控制臺(tái)輸出如下
那么問題來了,我改變的是對象的新值‘major’的值,請注意看我上面代碼中method方法中的設(shè)置obj的代碼。
此時(shí)Vue只是監(jiān)聽到了我改變了對象的新值。經(jīng)過我測試,我改變對象的舊值,比如name值。Vue依然監(jiān)聽不到對象的變化。此時(shí)Vue提出了深度監(jiān)聽的方法如下。
但是這種方法經(jīng)過我測試不能監(jiān)聽到對象新值的變化。
總結(jié)如下
總結(jié):如果操作對象是數(shù)組,改變數(shù)組的值用Vue的$set方法,改變數(shù)組的長度用數(shù)組的splice方法使數(shù)組變化變成可監(jiān)聽的。如果操作對象是對象。如果操作的屬性是對象內(nèi)已經(jīng)有的值,使用$watch,加上關(guān)鍵字deep深度監(jiān)聽對象,如果操作的屬性是對象內(nèi)沒有的新屬性。使用$set使對象變成可監(jiān)聽的!
到此這篇關(guān)于Vue踩坑之Vue Watch方法不能監(jiān)聽到數(shù)組或?qū)ο笾档母淖兊奈恼戮徒榻B到這了,更多相關(guān)Vue Watch方法不能監(jiān)聽數(shù)組內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue加載動(dòng)畫element ui V-loading屬性的踩坑記錄
這篇文章主要介紹了vue加載動(dòng)畫element ui V-loading屬性方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-06-06Vue動(dòng)態(tài)創(chuàng)建注冊component的實(shí)例代碼
這篇文章主要給大家介紹了關(guān)于Vue動(dòng)態(tài)創(chuàng)建注冊component的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用Vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-06-06Vue中使用JsonView來展示Json樹的實(shí)例代碼
這篇文章主要介紹了Vue之使用JsonView來展示Json樹的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11使用Element進(jìn)行前端開發(fā)的詳細(xì)圖文教程
眾所周知Element是一套Vue.js后臺(tái)組件庫,它能夠幫助你更輕松更快速地開發(fā)后臺(tái)項(xiàng)目,下面這篇文章主要給大家介紹了關(guān)于使用Element進(jìn)行前端開發(fā)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11基于Vue實(shí)現(xiàn)簡單的權(quán)限控制
這篇文章主要為大家學(xué)習(xí)介紹了如何基于Vue實(shí)現(xiàn)簡單的權(quán)限控制,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以了解一下2023-07-07