您好,登錄后才能下訂單哦!
這篇文章主要講解了“vue2怎么讓數組也變成響應式”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“vue2怎么讓數組也變成響應式”吧!
之前的代碼有個問題,就是操作數組數據的時候,不會觸發set
let data = { name: 'dean', age: 30, level1: { level2: { level3_1: { level4: { value: 'anna' } }, level3_2: { level4: { value: 'jing' } } } }, languages: ['javascript', 'java', 'c', 'pascal', 'python'] } observe(data) function observe(target) { // 如果不是對象或者數組就直接return 這也是地柜結束的條件 if (typeof target !== 'object' || target === null) return // 遍歷對象每個屬性 對每個屬性添加響應式 for(let k in target) { defineReactive(target, k, target[k]) } } function defineReactive(target, key, value) { // value子屬性的值 對其observe一下 遞歸 observe(value) // 再讓這個子屬性添加響應式 Object.defineProperty(target, key, { get() { return value }, set(newValue) { if (newValue === value) return // 設置新值也要observe一下 observe(newValue) value = newValue console.log('更新視圖') } }) } console.log(data.level1.level2.level3_1.level4.value) data.level1.level2.level3_1.level4.value = 'jing' console.log(data.level1.level2.level3_1.level4.value) data.languages.push('ruby') console.log(data.languages)
我們可以這樣修改來支持數組響應式操作:
let data = { name: 'dean', age: 30, level1: { level2: { level3_1: { level4: { value: 'anna' } }, level3_2: { level4: { value: 'jing' } } } }, languages: ['javascript', 'java', 'c', 'pascal', 'python'] } /** * 數組操作 */ const oldArrayProto = Array.prototype let newArrayProto = Object.create(oldArrayProto) let arr = ['push', 'pop', 'shift', 'unshift', 'splice', 'reverse', 'sort'] arr.forEach(methodName => { newArrayProto[methodName] = function() { console.log('自定義處理') // 保留原來的處理結果 return oldArrayProto[methodName].call(this, ...arguments) } }) function observe(target) { // 如果不是對象或者數組就直接按照原值return 這也是地柜結束的條件 if (typeof target !== 'object' || target === null) return target // 遍歷對象每個屬性 對每個屬性添加響應式 if (Array.isArray(target)) { Object.setPrototypeOf(target, newArrayProto) } for(let k in target) { defineReactive(target, k, target[k]) } } function defineReactive(target, key, value) { // value子屬性的值 對其observe一下 遞歸 observe(value) // 再讓這個子屬性添加響應式 Object.defineProperty(target, key, { get() { return value }, set(newValue) { if (newValue === value) return // 設置新值也要observe一下 observe(newValue) value = newValue console.log('更新視圖') } }) } observe(data) // console.log(data.level1.level2.level3_1.level4.value) // data.level1.level2.level3_1.level4.value = 'jing' // console.log(data.level1.level2.level3_1.level4.value) data.languages.push('ruby') console.log(data.languages)
響應式原理主要就是通過數據劫持,依賴收集,派發更新的方式來實現的
1.數據劫持,vue2是通過Object。defineProperty來將對象的每一個屬性轉化成set,get。
其中修改對象的屬性時 就會觸發set, 使用對象的屬性時就會觸發get
2.依賴收集。就是在渲染視圖時 將watcher和具體的屬性,通過發布訂閱者模式管理,這樣數據改變之后就能更精準的更新視圖
3.派發更新:它就是通過dep來執行watcher的notify方法
使用Object.defineProperty做響應式的缺點
1.深度監聽,需要一次性遞歸到底,計算量比較大
2.描述符只有get和set,無法監聽新增屬性和刪除屬性的操作
3.無法原生監聽數組
這三個缺點中,第二點是defineProperty本身API的缺陷,而第一點和第三點都是出于性能考慮而做的取舍
當我們通過數組的方法去更改數組時或是直接刪除data數據,數據并不能實現響應式,因為Object.defineProperty是沒有辦法處理屬性刪除和新增的
因此vue2的響應式,通過數組方法(prop,push),或是刪除,vue是不能監聽的
vue2中通過vue2中可以通過vue.datele和vue.set這些vue內置api來改變屬性,實現響應式。
感謝各位的閱讀,以上就是“vue2怎么讓數組也變成響應式”的內容了,經過本文的學習后,相信大家對vue2怎么讓數組也變成響應式這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。