成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

記一次思否問(wèn)答的問(wèn)題思考:Vue為什么不能檢測(cè)數(shù)組變動(dòng)

raoyi / 973人閱讀

摘要:這里加了個(gè)簡(jiǎn)單判斷,只看數(shù)組元素的,然后寫(xiě)了一個(gè)簡(jiǎn)單案例,主要測(cè)試使用改變數(shù)組元素能不能被監(jiān)測(cè)到,并響應(yīng)式的渲染頁(yè)面運(yùn)行頁(yè)面可以看到,運(yùn)行了次,我們數(shù)組長(zhǎng)度為,也就是說(shuō)數(shù)組被遍歷了兩遍。

問(wèn)題來(lái)源:https://segmentfault.com/q/10...

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

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

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

這句話(huà)是什么意思?我測(cè)試了下Object.defineProperty是可以通過(guò)索引屬性來(lái)設(shè)置屬性的訪問(wèn)器屬性的,那為何做不了監(jiān)聽(tīng)?

有些論壇上的人說(shuō)因?yàn)閿?shù)組長(zhǎng)度是可變的,即使長(zhǎng)度為5,但是未必有索引4,我就想問(wèn)問(wèn)這個(gè)答案哪里來(lái)的,修改length,新增的元素會(huì)被添加到最后,它的值為undefined,通過(guò)索引一樣可以獲取他們的值,怎么就叫做“未必有索引4”了呢?

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

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

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

var arr = [1]; arr[10000] = 1
function a(){
    console.time()
    for(var i = 0;i{console.log(2)})
    console.timeEnd()
}
b(); //default: 0.81982421875ms
b(); //default: 0.434814453125ms

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

其次,我要說(shuō)的是,我也不知道這個(gè)限制是什么 ???? (????) ???? ╮( ??ω?? )╭

Object.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象。數(shù)組的索引也是屬性,所以我們是可以監(jiān)聽(tīng)到數(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

但是我們新增一個(gè)元素,就不會(huì)觸發(fā)監(jiān)聽(tīng)事件,因?yàn)檫@個(gè)新屬性我們并沒(méi)有監(jiān)聽(tīng),刪除一個(gè)屬性也是。

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

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

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

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

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

運(yùn)行頁(yè)面

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

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

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

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

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

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

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

2018-07-27補(bǔ)充

github上提問(wèn)了尤大

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/96307.html

相關(guān)文章

  • 【半月刊 4】前端高頻面試題及答案匯總

    摘要:引言半月刊第四期來(lái)啦,這段時(shí)間新增了道高頻面試題,今天就把最近半月匯總的面試題和部分答案發(fā)給大家,幫助大家查漏補(bǔ)缺,歡迎加群互相學(xué)習(xí)。更多更全的面試題和答案匯總在下面的項(xiàng)目中,點(diǎn)擊查看。引言 半月刊第四期來(lái)啦,這段時(shí)間 Daily-Interview-Question 新增了 14 道高頻面試題,今天就把最近半月匯總的面試題和部分答案發(fā)給大家,幫助大家查漏補(bǔ)缺,歡迎 加群 互相學(xué)習(xí)。 更多更...

    hankkin 評(píng)論0 收藏0
  • 一次XX前端面試

    摘要:面試官說(shuō)那我問(wèn)你一個(gè)哲學(xué)的問(wèn)題,為什么有數(shù)據(jù)結(jié)構(gòu)這種東西哇,這是啥,巴拉巴拉扯了一通,大致就是物以類(lèi)聚,人以群分,先人積累下來(lái)的經(jīng)驗(yàn),這些讓我們更方便處理數(shù)據(jù)啥的。 前因,沒(méi)有比摸魚(yú)有趣的事了 距離自己被外派(俗稱(chēng)外包)出去,已經(jīng)過(guò)了快五個(gè)月,工作的話(huà),很閑。人啊,一定保持好的習(xí)慣,懶惰是會(huì)上癮,日常摸魚(yú),懷疑人生,我是誰(shuí),我在哪,我要干什么。 中午吃飯的時(shí)候,收到了boss直聘的一條...

    Shisui 評(píng)論0 收藏0
  • 使用Vue渲染可配置表單--一次問(wèn)卷平臺(tái)項(xiàng)目

    摘要:相當(dāng)于可以編輯問(wèn)卷并提供問(wèn)卷展示,數(shù)據(jù)統(tǒng)計(jì)的這么一個(gè)平臺(tái)。極大的節(jié)省了需要進(jìn)行表單樣式修改的時(shí)間,同時(shí),讓動(dòng)態(tài)渲染表單成為一件可能且容易的事情。表單動(dòng)態(tài)渲染剛好在項(xiàng)目之前,有過(guò)一次動(dòng)態(tài)配置表單的嘗試通過(guò)字段自動(dòng)生成表單及驗(yàn)證。 近幾天來(lái)了個(gè)緊急項(xiàng)目,想要做一個(gè)內(nèi)部版本的問(wèn)卷星。相當(dāng)于可以編輯問(wèn)卷并提供問(wèn)卷展示,數(shù)據(jù)統(tǒng)計(jì)的這么一個(gè)平臺(tái)。整個(gè)項(xiàng)目耗時(shí)不長(zhǎng),本著積淀和積累的原則,將過(guò)程中的...

    mcterry 評(píng)論0 收藏0
  • 記錄vue不能檢測(cè)數(shù)組和對(duì)象變動(dòng)方法。

    摘要:當(dāng)然按照官方文檔的解釋?zhuān)瑱z測(cè)不到的主要問(wèn)題是導(dǎo)致的。下列代碼,是解決數(shù)組檢測(cè)不到的問(wèn)題。 測(cè)試數(shù)據(jù): items: [ {name: 業(yè)務(wù)狀態(tài), id: taskState, data: [{name:全部, id: 0},{name:進(jìn)行中, id: 1},{name:已完成, id: 2},{name:已歸檔, id: 3},{name:已終止, id: 4}]}, ...

    Clect 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<