最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue數(shù)組的劫持逐步分析講解

 更新時間:2023年01月06日 15:59:25   作者:BraveWangDev  
小編這次要給大家分享的是如何實現(xiàn)vue2.x數(shù)組劫持,文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲

一,前言

上篇,主要介紹了 Vue 數(shù)據(jù)初始化流程中,對象屬性的深層劫持是如何實現(xiàn)的

核心思路就是遞歸,主要流程如下;

1.通過 data = isFunction(data) ? data.call(vm) : data;處理后的 data 一定是對象類型

2.通過 data = observe(data)處理后的 data 就實現(xiàn)了數(shù)據(jù)的響應(yīng)式(目前只有劫持)

3.observe 方法最終返回一個 Observer 類

4.Observer 類初始化時,通過 walk 遍歷屬性

5.對每一個屬性進行 defineReactive(Object.defineProperty)就實現(xiàn)對象屬性的單層數(shù)據(jù)劫持

6.在 defineReactive 中,如果屬性值為對象類型就繼續(xù)調(diào)用 observe 對當前的對象屬性進行觀測(即遞歸步驟 3~5),這樣就實現(xiàn)了對象屬性的深層數(shù)據(jù)劫持

本篇,繼續(xù)介紹 Vue 數(shù)據(jù)初始化流程中,對于數(shù)組類型的劫持

二,對象劫持回顧

1,Demo

data 數(shù)據(jù)中對象屬性的深層觀測,即對象屬性為對象(包含多層)的情況

let vm = new Vue({
  el: '#app',
  data() {
    return { message: 'Hello Vue', obj: { key: "val" }, a: { a: { a: {} } } }
});

當 data 中的屬性為數(shù)組時,Vue 是如何進行處理的

三,數(shù)組類型的處理

1,當前邏輯分析

按照當前版本的處理邏輯,所有對象類型會對被進行深層觀測,數(shù)組也不例外

let vm = new Vue({
  el: '#app',
  data() {
    return { message: 'Hello Vue', obj: { key: "val" }, arr:[1,2,3]}
  }
});

可以看到,數(shù)組中的每一項,都被添加了 get、set 方法,也就相當于實現(xiàn)了對數(shù)組的深層觀測

備注:Object.defineProperty支持數(shù)組數(shù)據(jù)類型的劫持

2,Vue 對性能的權(quán)衡

在 Vue2.x 中,不支持通過修改數(shù)組索引和長度的數(shù)據(jù)劫持;

那么,為什么原本可以實現(xiàn)對數(shù)組索引的觀測,Vue 卻選擇了不支持呢?

主要是考慮了性能問題,比如,數(shù)組中的數(shù)據(jù)量非常大時:

let vm = new Vue({
  el: '#app',
  data() {
    return { arr:new Array(9999) }
  }
});

這時,數(shù)組中 9999 條數(shù)據(jù),將全部被添加 get、set 方法

而這一套操作就比較費勁了:為了實現(xiàn)數(shù)組索引劫持,需要對數(shù)組中每一項進行處理

還有就是,雖然數(shù)組能夠通過 defineProperty 實現(xiàn)對索引更新劫持

但在實際開發(fā)場景真的需要嗎?似乎很少會使用 arr[888] = x 這種操作

所以,權(quán)衡性能和需求,Vue 源碼中沒有采用 defineProperty 對數(shù)組進行處理

當然,這也就導(dǎo)致了在 Vue 中無法通過直接修改索引、length 觸發(fā)視圖的更新

3,數(shù)組的劫持思路

核心目標是要實現(xiàn)數(shù)組的響應(yīng)式:

Vue 認為這 7 個方法能夠改變原數(shù)組:push、pop、splice、shift、unshift、reverse、sort

所以,只要對這 7 個方法進行處理,就能劫持到數(shù)組的數(shù)據(jù)變化,實現(xiàn)數(shù)組數(shù)據(jù)的響應(yīng)式

備注:這種實現(xiàn)思路,也直接導(dǎo)致了 vue2 修改數(shù)組的索引和長度不能觸發(fā)視圖更新

梳理對象屬性深層劫持的實現(xiàn):

  • 數(shù)據(jù)觀測入口:src/observe/index.js#observe方法
  • 如果數(shù)據(jù)為對象類型就 new Observer
  • Observer 初始化時,會遍歷對象屬性,逐一遞歸 Object.defineProperty

數(shù)組也是對象,所以,要把數(shù)組的處理邏輯單獨拆出來。即對 7 個變異方法進行重寫

// src/utils
/**
 * 判斷是否是數(shù)組
 * @param {*} val 
 * @returns 
 */
export function isArray(val) {
  return Array.isArray(val)
}
// src/observe/index.js
import { arrayMethods } from "./array";
class Observer {
  constructor(value) {
    if(isArray(value)){
      // 對數(shù)組類型進行單獨處理:重寫 7 個變異方法
    }else{
      this.walk(value);
    }
  }
}

4,數(shù)組方法的攔截思路

  • 重寫方法需要在原生方法基礎(chǔ)上,實現(xiàn)對數(shù)據(jù)變化的劫持操作
  • 僅對響應(yīng)式數(shù)據(jù)中的數(shù)組進行方法重寫,不能影響非響應(yīng)式數(shù)組

所以,對響應(yīng)式數(shù)據(jù)中數(shù)組這 7 個方法進行攔截,即優(yōu)先使用重寫方法,其他方法還走原生邏輯

數(shù)組方法的查找,先查找自己身上的方法(即重寫方法),找不到再去鏈上查(原生方法)

5,數(shù)組方法重寫的實現(xiàn)

// src/Observer/array.js
// 拿到數(shù)組的原型方法
let oldArrayPrototype = Array.prototype;
// 原型繼承,將原型鏈向后移動 arrayMethods.__proto__ == oldArrayPrototype
export let arrayMethods = Object.create(oldArrayPrototype);
// 重寫能夠?qū)е略瓟?shù)組變化的七個方法
let methods = [
  'push',
  'pop',
  'shift',
  'unshift',
  'reverse',
  'sort',
  'splice'
]
// 在數(shù)組自身上進行方法重寫,對鏈上的同名方法進行攔截
methods.forEach(method => {
  arrayMethods[method] = function () {
    console.log('數(shù)組的方法進行重寫操作 method = ' + method)
  }
});

添加 new Observer 時,對數(shù)組方法重寫的邏輯:

// src/observe/index.js
import { arrayMethods } from "./array";
class Observer {
  constructor(value) {
    // 分別處理 value 為數(shù)組和對象兩種情況
    if(isArray(value)){
      value.__proto__ = arrayMethods; // 更改數(shù)組的原型方法
    }else{
      this.walk(value);
    }
  }
}

測試數(shù)組方法的重寫:

數(shù)組的鏈:

  • array.proto:包含 7 個重寫方法
  • array.proto.proto:原始方法

6,數(shù)組方法攔截的實現(xiàn)

// src/state.js#initData
function initData(vm) {
    let data = vm.$options.data;
    data = isFunction(data) ? data.call(vm) : data;
    observe(data);	// 在observe方法中new Observer執(zhí)行后,數(shù)組的原型方法已完成重寫
    // 測試數(shù)組方法的攔截效果
    data.arr.push(666); 
    data.arr.pop()
}

  • arrayMethods.push:會在數(shù)組自身找到重寫的push方法,不會繼續(xù)到鏈上查找,實現(xiàn)攔截
  • arrayMethods.pop:數(shù)組自身沒找到重寫方法,繼續(xù)到鏈上找到原生pop方法

四,結(jié)尾

本篇主要介紹了 Vue 數(shù)據(jù)初始化流程中,數(shù)組類型的數(shù)據(jù)劫持,核心有以下幾點:

出于對性能的考慮,Vue 沒有對數(shù)組類型的數(shù)據(jù)使用 Object.defineProperty 進行遞歸劫持,而是通過對能夠?qū)е略瓟?shù)組變化的 7 個方法進行攔截和重寫實現(xiàn)了數(shù)據(jù)劫持

下一篇,數(shù)據(jù)代理的實現(xiàn)

到此這篇關(guān)于Vue數(shù)組的劫持逐步分析講解的文章就介紹到這了,更多相關(guān)Vue數(shù)組劫持內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • elementUI多選框反選的實現(xiàn)代碼

    elementUI多選框反選的實現(xiàn)代碼

    這篇文章主要介紹了elementUI多選框反選的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 在vue中使用vant TreeSelect分類選擇組件操作

    在vue中使用vant TreeSelect分類選擇組件操作

    這篇文章主要介紹了在vue中使用vant TreeSelect分類選擇組件操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11
  • Vue自定義指令實現(xiàn)對數(shù)字進行千分位分隔

    Vue自定義指令實現(xiàn)對數(shù)字進行千分位分隔

    對數(shù)字進行千分位分隔后展示應(yīng)該是大部分同學(xué)都做過的功能了吧,常規(guī)的做法通常是編寫一個工具函數(shù)來對數(shù)據(jù)進行轉(zhuǎn)換,那么我們可不可以通過vue指令來實現(xiàn)這一功能呢,下面我們就來探索一下呢
    2024-02-02
  • vue中el-input綁定鍵盤按鍵(按鍵修飾符)

    vue中el-input綁定鍵盤按鍵(按鍵修飾符)

    這篇文章主要介紹了vue中el-input綁定鍵盤按鍵(按鍵修飾符),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 解決在Vue中使用axios用form表單出現(xiàn)的問題

    解決在Vue中使用axios用form表單出現(xiàn)的問題

    今天小編就為大家分享一篇解決在Vue中使用axios用form表單出現(xiàn)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • vuejs中使用mixin局部混入/全局混入的方法詳解

    vuejs中使用mixin局部混入/全局混入的方法詳解

    混入可以省很多代碼(高類聚低耦合),還方便維護,下面這篇文章主要給大家介紹了關(guān)于vuejs中使用mixin局部混入/全局混入的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-05-05
  • 詳解Vue-基本標簽和自定義控件

    詳解Vue-基本標簽和自定義控件

    本篇文章主要介紹了Vue-基本標簽和自定義控件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • 解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題

    解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題

    這篇文章主要介紹了解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • vue遍歷生成的輸入框 綁定及修改值示例

    vue遍歷生成的輸入框 綁定及修改值示例

    今天小編就為大家分享一篇vue遍歷生成的輸入框 綁定及修改值示例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-10-10
  • Vue 搭建Vuex環(huán)境詳解

    Vue 搭建Vuex環(huán)境詳解

    這篇文章主要為大家介紹了Vue搭建Vuex環(huán)境,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11

最新評論

庆元县| 哈尔滨市| 恩平市| 高州市| 宝鸡市| 延长县| 安远县| 安庆市| 深泽县| 惠水县| 辽阳县| 察雅县| 宁武县| 泽普县| 阿克苏市| 石首市| 古丈县| 汶上县| 阳高县| 北碚区| 布拖县| 博客| 会东县| 华坪县| 香格里拉县| 江津市| 久治县| 晋城| 宁陕县| 通渭县| 永兴县| 铅山县| 沁源县| 拉孜县| 苍梧县| 文昌市| 宝丰县| 渭源县| 集安市| 吉安县| 云龙县|