欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Vue為什么不能檢測數(shù)組變動

 更新時間:2019年10月14日 10:11:36   作者:hfhan  
這篇文章主要介紹了淺談Vue為什么不能檢測數(shù)組變動,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

問題來源:https://segmentfault.com/q/1010000015780995

問題描述:Vue檢測數(shù)據(jù)的變動是通過Object.defineProperty實現(xiàn)的,所以無法監(jiān)聽數(shù)組的添加操作是可以理解的,因為是在構(gòu)造函數(shù)中就已經(jīng)為所有屬性做了這個檢測綁定操作。

但是官方的原文:由于 JavaScript 的限制, Vue 不能檢測以下變動的數(shù)組:

當(dāng)你利用索引直接設(shè)置一個項時,例如: vm.items[indexOfItem] = newValue
當(dāng)你修改數(shù)組的長度時,例如: vm.items.length = newLength

這句話是什么意思?我測試了下Object.defineProperty是可以通過索引屬性來設(shè)置屬性的訪問器屬性的,那為何做不了監(jiān)聽?

有些論壇上的人說因為數(shù)組長度是可變的,即使長度為5,但是未必有索引4,我就想問問這個答案哪里來的,修改length,新增的元素會被添加到最后,它的值為undefined,通過索引一樣可以獲取他們的值,怎么就叫做“未必有索引4”了呢?

既然知道數(shù)組的長度為何不能遍歷所有元素并通過索引這個屬性全部添加set和get不就可以同時更新視圖了嗎?

如果非要說的話,考慮到性能的問題,假設(shè)元素內(nèi)容只有4個有意義的值,但是長度確實1000,我們不可能為1000個元素做檢測操作。但是官方說的由于JS限制,我想知道這個限制是什么內(nèi)容?各位大大幫我解決下這個問題,感謝萬分

面對這個問題,我想說的是,首先,長度為1000,但只有4個元素的數(shù)組并不一定會影響性能,因為js中對數(shù)據(jù)的遍歷除了for循環(huán)還有forEach、map、filter、some等,除了for循環(huán)外(for,for...of),其他的遍歷都是對鍵值的遍歷,也就是除了那四個元素外的空位并不會進(jìn)行遍歷(執(zhí)行回調(diào)),所以也就不會造成性能損耗,因為循環(huán)體中沒有操作的話,所帶來的性能影響可以忽略不計,下面是長度為10000,但只有兩個元素的數(shù)組分別使用for及forEach遍歷的結(jié)果:

var arr = [1]; arr[10000] = 1
function a(){
  console.time()
  for(var i = 0;i<arr.length;i++)console.log(1)
  console.timeEnd()
}
a(); //default: 567.1669921875ms
a(); //default: 566.2451171875ms

function b(){
  console.time()
  arr.forEach(item=>{console.log(2)})
  console.timeEnd()
}
b(); //default: 0.81982421875ms
b(); //default: 0.434814453125ms

可以看到結(jié)果非常明顯,不過,如果for循環(huán)中不做操作的話兩者速度差不多

其次,我要說的是,我也不知道這個限制是什么 (⇀‸↼‶) ╮( •́ω•̀ )╭

Object.defineProperty() 方法會直接在一個對象上定義一個新屬性,或者修改一個對象的現(xiàn)有屬性, 并返回這個對象。數(shù)組的索引也是屬性,所以我們是可以監(jiān)聽到數(shù)組元素的變化的

var arr = [1,2,3,4]
arr.forEach((item,index)=>{
  Object.defineProperty(arr,index,{
    set:function(val){
      console.log('set')
      item = val
    },
    get:function(val){
      console.log('get')
      return item
    }
  })
})
arr[1]; // get 2
arr[1] = 1; // set 1

但是我們新增一個元素,就不會觸發(fā)監(jiān)聽事件,因為這個新屬性我們并沒有監(jiān)聽,刪除一個屬性也是。

再回到題主的問題,既然數(shù)組是可以被監(jiān)聽的,那為什么vue不能檢測vm.items[indexOfItem] = newValue導(dǎo)致的數(shù)組元素改變呢,哪怕這個下標(biāo)所對應(yīng)的元素是存在的,且被監(jiān)聽了的?

為了搞清楚這個問題,我用vue的源碼測試了下,下面是vue對數(shù)據(jù)監(jiān)測的源碼:

可以看到,當(dāng)數(shù)據(jù)是數(shù)組時,會停止對數(shù)據(jù)屬性的監(jiān)測,我們修改一下源碼:

使數(shù)據(jù)為數(shù)組時,依然監(jiān)測其屬性,然后在defineReactive函數(shù)中的get,set打印一些東西,方便我們知道調(diào)用了get以及set。這里加了個簡單判斷,只看數(shù)組元素的get,set

然后寫了一個簡單案例,主要測試使用vm.items[indexOfItem] = newValue改變數(shù)組元素能不能被監(jiān)測到,并響應(yīng)式的渲染頁面

運(yùn)行頁面

可以看到,運(yùn)行了6次get,我們數(shù)組長度為3,也就是說數(shù)組被遍歷了兩遍。兩遍不多,頁面渲染一次,可能多次觸發(fā)一個數(shù)據(jù)的監(jiān)聽事件,哪怕這個數(shù)據(jù)只用了一次,具體的需要看尤大代碼怎么寫的。就拿這個來說,當(dāng)監(jiān)聽的數(shù)據(jù)為數(shù)組時,會運(yùn)行dependArray函數(shù)(代碼在上面圖中g(shù)et的實現(xiàn)里),這個函數(shù)里對數(shù)組進(jìn)行了遍歷取值操作,所以會多3遍get,這里主要是vue對data中arr數(shù)組的監(jiān)聽觸發(fā)了dependArray函數(shù)。

當(dāng)我們點(diǎn)擊其中一個元素的時候,比如我點(diǎn)擊的是3

可以看到會先運(yùn)行一次set,然后數(shù)據(jù)更新,重新渲染頁面,數(shù)組又是被遍歷了兩遍。

但是?。?!數(shù)組確實變成響應(yīng)式的了,也就是說js語法功能并不會限制數(shù)組的監(jiān)測。

這里我們是用長度為3的數(shù)組測試的,當(dāng)我把數(shù)組長度增加到9時

可以看到,運(yùn)行了18次get,數(shù)組還是被遍歷了兩遍,點(diǎn)擊某個元素同理,渲染的時候也是被遍歷兩次。

有了上面的實驗,我的結(jié)論是數(shù)組在vue中是可以實現(xiàn)響應(yīng)式更新的,但是不明白尤大是出于什么考慮,沒有加入這一功能,希望有知道的大佬們不吝賜教

2018-07-27補(bǔ)充

github上提問了尤大

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue組件大全包括(UI組件,開發(fā)框架,服務(wù)端,輔助工具,應(yīng)用實例,Demo示例)

    Vue組件大全包括(UI組件,開發(fā)框架,服務(wù)端,輔助工具,應(yīng)用實例,Demo示例)

    本文為大家分享了網(wǎng)上比較流行的Vue組件,包括UI組件,開發(fā)框架,服務(wù)端,輔助工具,應(yīng)用實例,Demo示例等開源項目,總有一款適合你
    2018-10-10
  • ToB項目如何沉淀業(yè)務(wù)公共組件示例詳解

    ToB項目如何沉淀業(yè)務(wù)公共組件示例詳解

    這篇文章主要為大家介紹了ToB項目如何沉淀業(yè)務(wù)公共組件示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • VUE中常用的四種高級方法總結(jié)

    VUE中常用的四種高級方法總結(jié)

    開發(fā)vue項目的時候一般都會開發(fā)很多自定義的全局組件,下面這篇文章主要給大家總結(jié)介紹了關(guān)于VUE中常用的四種高級方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • proxy實現(xiàn)vue3數(shù)據(jù)雙向綁定原理

    proxy實現(xiàn)vue3數(shù)據(jù)雙向綁定原理

    這篇文章主要介紹了proxy實現(xiàn)vue3數(shù)據(jù)雙向綁定原理,文章以介紹proxy的優(yōu)點(diǎn)開始展開全文內(nèi)容,圍繞proxy實現(xiàn)vue3數(shù)據(jù)雙向綁定的相關(guān)資料,,需要的朋友可以參考一下
    2021-12-12
  • vue3如何用pinia替代vuex

    vue3如何用pinia替代vuex

    這篇文章主要介紹了vue3如何使用pinia替代vuex問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue實現(xiàn)倒計時獲取驗證碼效果

    vue實現(xiàn)倒計時獲取驗證碼效果

    這篇文章主要為大家詳細(xì)介紹了vue實現(xiàn)倒計時獲取驗證碼效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-09-09
  • Vue路由this.route.push跳轉(zhuǎn)頁面不刷新的解決方案

    Vue路由this.route.push跳轉(zhuǎn)頁面不刷新的解決方案

    這篇文章主要介紹了Vue路由this.route.push跳轉(zhuǎn)頁面不刷新的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Vue實現(xiàn)色板功能的示例代碼

    Vue實現(xiàn)色板功能的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用Vue實現(xiàn)色板功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價值,感興趣的小伙伴可以了解一下
    2023-06-06
  • Element Timeline時間線的實現(xiàn)

    Element Timeline時間線的實現(xiàn)

    本文主要介紹了Element Timeline時間線的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • Vuex的初探與實戰(zhàn)小結(jié)

    Vuex的初探與實戰(zhàn)小結(jié)

    這篇文章主要介紹了Vuex的初探與實戰(zhàn)小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-11-11

最新評論