解決vue中數(shù)據(jù)更新視圖不更新問題this.$set()方法
vue數(shù)據(jù)更新視圖不更新
1.data中有對象obj :{name:'遠航',age:18}
2.此時新增phone
this.obj.phone = '123456'
再次更新 用this.obj.phone = '654321' 視圖未更新 用this.$set(this.obj,"phone", "654321");也未更新
3.添加完成以后數(shù)據(jù)有更新,視圖未更新,
解決問題
因為obj中沒有phone字段,第一次新增屬性的時候就要用this.$set(this.obj,"phone", "123456");就可以了
我第一次新增屬性沒有用this.$set(),因此沒有建立數(shù)據(jù)監(jiān)聽
新增多個屬性方法
// 代替 `Object.assign(this.someObject, { a: 1, b: 2 })` this.someObject = Object.assign({}, this.someObject, { a: 1, b: 2 })
vue數(shù)據(jù)不更新的原因(數(shù)據(jù)更改了,但是視圖沒有更新)
templete:
<div id="app"> ? ? ? ? <h2>{{dataObj.text}}</h2> </div>
js:
new Vue({ ? ? ? ? ? ? el: '#app', ? ? ? ? ? ? data: { ? ? ? ? ? ? ? ? dataObj: {} ? ? ? ? ? ? }, ? ? ? ? ? ? ready: function () { ? ? ? ? ? ? ? ? var self = this; ? ? ? ? ? ? ? ? /** ? ? ? ? ? ? ? ? ?* 異步請求模擬 ? ? ? ? ? ? ? ? ?*/ ? ? ? ? ? ? ? ? setTimeout(function () { ? ? ? ? ? ? ? ? ? ? self.dataObj = {};//真正實現(xiàn)數(shù)據(jù)更新的是這行代碼 ? ? ? ? ? ? ? ? ? ? self.dataObj['text'] = 'new text'; ? ? ? ? ? ? ? ? }, 3000); ? ? ? ? ? ? } })
上面的代碼非常簡單,我們都知道vue中在data里面聲明的數(shù)據(jù)才具有響應式的特性,所以我們一開始在data中聲明了一個dataObj空對象,然后在異步請求中執(zhí)行了兩行代碼,如下:
self.dataObj = {}; self.dataObj['text'] = 'new text';
解決辦法
首先清空原始數(shù)據(jù),然后添加一個text屬性并賦值。然后數(shù)據(jù)和模版都更新里。
其中.text屬性不具有響應式,但是數(shù)據(jù)更新了。原因:
vue的dom更新是異步的,即當setter操作發(fā)生后,指令并不會立馬更新,指令的更新操作會有一個延遲,當指令更新真正執(zhí)行的時候,此時.text屬性已經(jīng)賦值,所以指令更新模板時得到的是新值。
具體流程如下
- self.dataObj = {};發(fā)生setter操作
- vue監(jiān)測到setter操作,通知相關指令執(zhí)行更新操作
- self.dataObj[‘text’] = ‘new text’;賦值語句
- 指令更新開始執(zhí)行
所以真正的觸發(fā)更新操作是self.dataObj = {};這一句引起的,所以單看上述例子,具有響應式特性的數(shù)據(jù)只有dataObj這一層,它的子屬性是不具備的。
數(shù)組更新檢測
Vue 包含一組觀察數(shù)組的變異方法,所以它們也將會觸發(fā)視圖更新。這些方法如下:
push()
pop()
shift()
unshift()
splice()
sort()
reverse()
注意事項
由于 JavaScript 的限制,Vue 不能檢測以下變動的數(shù)組:
當你利用索引直接設置一個項時,例如:vm.items[indexOfItem] = newValue
當你修改數(shù)組的長度時,例如:vm.items.length = newLength
舉個例子:
var vm = new Vue({ ? data: { ? ? items: ['a', 'b', 'c'] ? } }) vm.items[1] = 'x' // 不是響應性的 vm.items.length = 2 // 不是響應性的
為了解決第一類問題,以下兩種方式都可以實現(xiàn)和vm.items[indexOfItem] = newValue相同的效果,同時也將觸發(fā)狀態(tài)更新:
// Vue.set Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名:
vm.$set(vm.items, indexOfItem, newValue)
為了解決第二類問題,你可以使用 splice:
vm.items.splice(newLength)
對象更改檢測注意事項
還是由于 JavaScript 的限制,Vue 不能檢測對象屬性的添加或刪除:
var vm = new Vue({ ? data: { ? ? a: 1 ? } }) // `vm.a` 現(xiàn)在是響應式的 vm.b = 2 // `vm.b` 不是響應式的
對于已經(jīng)創(chuàng)建的實例,Vue 不能動態(tài)添加根級別的響應式屬性。但是,可以使用 Vue.set(object, key, value)方法向嵌套對象添加響應式屬性。例如,對于:
var vm = new Vue({ ? data: { ? ? userProfile: { ? ? ? name: 'Anika' ? ? } ? } })
你可以添加一個新的 age 屬性到嵌套的 userProfile 對象:
Vue.set(vm.userProfile, 'age', 27)
你還可以使用 vm.$set 實例方法,它只是全局 Vue.set 的別名:
vm.$set(vm.userProfile, 'age', 27)
有時你可能需要為已有對象賦予多個新屬性,比如使用 Object.assign() 或 _.extend()。在這種情況下,你應該用兩個對象的屬性創(chuàng)建一個新的對象。所以,如果你想添加新的響應式屬性,不要像這樣:
Object.assign(vm.userProfile, { ? age: 27, ? favoriteColor: 'Vue Green' })
你應該這樣做:
vm.userProfile = Object.assign({}, vm.userProfile, { ? age: 27, ? favoriteColor: 'Vue Green' })
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Vue 2.5.2下axios + express 本地請求404的解決方法
下面小編就為大家分享一篇Vue 2.5.2下axios + express 本地請求404的解決方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2018-02-02Vue.js 利用v-for中的index值實現(xiàn)隔行變色
這篇文章主要介紹了Vue.js 利用v-for中的index值實現(xiàn)隔行變色效果,首先定義好樣式,利用v-for中的index值,然后綁定樣式來實現(xiàn)隔行變色,需要的朋友可以參考下2018-08-08elementui中的el-cascader級聯(lián)選擇器的實踐
本文主要介紹了elementui中的el-cascader級聯(lián)選擇器的實踐,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-10-10詳解使用vue-router進行頁面切換時滾動條位置與滾動監(jiān)聽事件
本篇文章主要介紹了詳解使用vue-router進行頁面切換時滾動條位置與滾動監(jiān)聽事件,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2017-03-03