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

關(guān)于Vue?監(jiān)控數(shù)組的問題

 更新時間:2022年05月28日 10:24:33   作者:拜小白  
這篇文章主要介紹了Vue?監(jiān)控數(shù)組的示例,主要包括Vue?是如何追蹤數(shù)據(jù)發(fā)生變化,Vue?如何更新數(shù)組以及為什么有些數(shù)組的數(shù)據(jù)變更不能被?Vue?監(jiān)測到,對vue監(jiān)控數(shù)組知識是面試比較常見的問題,感興趣的朋友一起看看吧

常見面試題

  • Vue 如何監(jiān)控數(shù)組
  • defineProperty 真的不能監(jiān)測數(shù)組變化嗎?

Vue 是如何追蹤數(shù)據(jù)發(fā)生變化

在 Vue 中當我們把一個普通的 JS 對象作為 data 傳入 Vue 實例,Vue2.x 對這個數(shù)據(jù)初始化時將遍歷這個對象所有的屬性,并使用 JS 的原生特性 Object.defineProperty 把這些屬性全部轉(zhuǎn)為 getter\setter。這些 getter\setter 對用戶來說是不可見的,他們可以在屬性被訪問和修改時通知變更。同時每個組件實例都對應一個 watcher 實例,它會在組件渲染的過程中把“接觸”過的數(shù)據(jù)屬性記錄為依賴。之后當依賴項的 setter 觸發(fā)時,會通知 watcher,從而使它關(guān)聯(lián)的組件重新渲染。

Vue 如何更新數(shù)組

// 方法一: 使用 Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// 方法二: 使用 Vue 可監(jiān)測的數(shù)組變異方法: Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

為什么有些數(shù)組的數(shù)據(jù)變更不能被 Vue 監(jiān)測到

簡單來說,我們操作數(shù)組的一些動作 arr[2] = 'xxx' / arr.length = 2 或者是調(diào)用 Array.prototype 上掛載的部分方法并不能觸發(fā)這個屬性的 setter。

在數(shù)組的更新中有提到,可以使用 Vue 可監(jiān)測的數(shù)組變異方法: Array.prototype.splice, 哪為什么這個方法可以觸發(fā)狀態(tài)的更新了。 這是因為 Vue2.x 將數(shù)組的 7 個常用方法 push、pop、shift、unshift、splice、sort、reverse 進行了重寫,所以通過調(diào)用包裝之后的數(shù)組方法就能夠被 Vue 監(jiān)測到。

// Vue 2.6.14 
// src/core/observer/array.js
import { def } from '../util/index'
 
// 記錄原始 Array 未重寫之前的 API 原型方法
const arrayProto = Array.prototype
// 深拷貝一份上面的原型出來
export const arrayMethods = Object.create(arrayProto)
 
const methodsToPatch = [
  'push',
  'pop',
  'shift',
  'unshift',
  'splice',
  'sort',
  'reverse'
]
 
/**
 * Intercept mutating methods and emit events
 * 攔截上邊數(shù)組中列出的變異方法, 并發(fā)出事件通知
 */
methodsToPatch.forEach(function (method) {
  // cache original method
  // 緩存 Array.prototype 中的同名原始方法
  const original = arrayProto[method]
  def(arrayMethods, method, function mutator (...args) {
    // 調(diào)用執(zhí)行原有的數(shù)組方法
    const result = original.apply(this, args)
    const ob = this.__ob__
    let inserted
    switch (method) {
      case 'push':
      case 'unshift':
        inserted = args
        break
      case 'splice':
        inserted = args.slice(2)
        break
    }
    // 如果是插入的數(shù)據(jù),將它再次監(jiān)聽起來
    if (inserted) ob.observeArray(inserted)
    // 觸發(fā)訂閱,像頁面更新響應就在這里觸發(fā)
    ob.dep.notify()
    return result
  })
})

Vue 為什么不能通過下標操作數(shù)組或者改變數(shù)組的長度來觸發(fā)視圖更新

那 Vue2.x 監(jiān)測數(shù)組變更的兩條限制:不能監(jiān)聽利用索引直接設(shè)置一個數(shù)組項,不能監(jiān)聽直接修改數(shù)組的長度,是因為 defineProperty 的限制么?

答案:是的

Object.defineProperty 對于數(shù)組變化監(jiān)聽的表現(xiàn)與 Vue2.x 還是有不同的,比如 Object.defineProperty 可以監(jiān)聽到通過索引直接修改數(shù)組項,當然也不是說 Object.defineProperty 可以完全監(jiān)聽數(shù)組的變化,像直接修改數(shù)組的長度或者 push\pop 之類的方法還是不能觸發(fā) setter 的。

這里就會出現(xiàn)一個新的問題?

為什么 Object.defineProperty 明明能監(jiān)聽到數(shù)組值的變化,而 Vue 卻沒有實現(xiàn)呢?

這是因為 Vue 是對數(shù)組元素進行了監(jiān)聽,而沒有對數(shù)組本身的變化進行監(jiān)聽。

var Observer = function Observer (value) {
    this.value = value;
    this.dep = new Dep();
    this.vmCount = 0;
    def(value, '__ob__', this);
    // 區(qū)分對象和數(shù)組,對象和數(shù)組走不通的響應式方案
    if (Array.isArray(value)) {
      // 判斷是否支持__proto__屬性,根據(jù)不同的請求來添加數(shù)組的攔截方法
      if (hasProto) {
        protoAugment(value, arrayMethods);
      } else {
        copyAugment(value, arrayMethods, arrayKeys);
      }
      // 循環(huán)數(shù)組的元素,再次調(diào)用observe方法,
      this.observeArray(value);
    } else {
      // 如果是對象,循環(huán)對象屬性,為對象屬性添加getter,setter方法,將屬性變成響應式
      this.walk(value);
    }
  };

這其實是出于性能原因的考量,給每一個數(shù)組元素綁定上監(jiān)聽,實際消耗很大而受益并不大。

其實還有一些考慮是:對數(shù)據(jù)的操作更常用的操作數(shù)組的方法是使用數(shù)組原型上的一些方法如 push、shift 等來操作數(shù)組。Object.defineProperty是對象上的方法,用來對數(shù)組的下標進行檢測,會改變數(shù)據(jù)本來的性質(zhì)。

總結(jié)來說:三點原因

  • 性能原因的考量
  • 對數(shù)據(jù)的操作更常用的操作數(shù)組的方法是使用數(shù)組原型上的一些方法如 push、shift 等來操作數(shù)組。
  • Object.defineProperty是對象上的方法,用來對數(shù)組的下標進行檢測,會改變數(shù)據(jù)本來的性質(zhì)。

當然最重要的就是性能問題。

Vue 3.0 是如何處理的?

Vue3 不再采用 defineProperty 的方式來進行監(jiān)聽而是采用 Proxy 的方式。下面我引用了 MDN 上對于 proxy 的介紹: Proxy 對象用于創(chuàng)建一個對象的代理,從而實現(xiàn)基本操作的攔截和自定義(如屬性查找、賦值、枚舉、函數(shù)調(diào)用等)。 當異步觸發(fā) Model 里的數(shù)據(jù)變化時,都會經(jīng)過 Proxy 這一層,在這里則可以監(jiān)聽數(shù)組以及各種數(shù)據(jù)類型的變化,無論是數(shù)組下標賦值引起變化還是數(shù)組方法引起變化,都可以被監(jiān)聽到,也可以避開監(jiān)聽數(shù)組每個屬性下造成的性能問題。

參考

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

相關(guān)文章

  • Vue?Router組合布局用法詳解

    Vue?Router組合布局用法詳解

    今天我們用一種新的布局方式,使用路由視圖來實現(xiàn)布局樣式,本文將給大家介紹如何使用Vue?Router組合布局,文中有詳細的代碼示例供大家參考,感興趣的同學可以跟著小編一起學習
    2023-05-05
  • vue-admin-template框架搭建及應用小結(jié)

    vue-admin-template框架搭建及應用小結(jié)

    ?vue-admin-template是基于vue-element-admin的一套后臺管理系統(tǒng)基礎(chǔ)模板(最少精簡版),可作為模板進行二次開發(fā),這篇文章主要介紹了vue-admin-template框架搭建及應用,需要的朋友可以參考下
    2023-05-05
  • vue實現(xiàn)簡單數(shù)據(jù)雙向綁定

    vue實現(xiàn)簡單數(shù)據(jù)雙向綁定

    這篇文章主要為大家詳細介紹了vue實現(xiàn)簡單數(shù)據(jù)雙向綁定,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • vue3利用store實現(xiàn)記錄滾動位置的示例

    vue3利用store實現(xiàn)記錄滾動位置的示例

    這篇文章主要介紹了vue3利用store實現(xiàn)記錄滾動位置的示例,幫助大家更好的理解和學習使用vue框架,感興趣的朋友可以了解下
    2021-04-04
  • Vue3中createWebHistory和createWebHashHistory的區(qū)別詳析

    Vue3中createWebHistory和createWebHashHistory的區(qū)別詳析

    這篇文章主要給大家介紹了關(guān)于Vue3中createWebHistory和createWebHashHistory區(qū)別的相關(guān)資料,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-06-06
  • vue中的vue-router?query方式和params方式詳解

    vue中的vue-router?query方式和params方式詳解

    這篇文章主要介紹了vue中的vue-router?query方式和params方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue3+vite 動態(tài)引用靜態(tài)資源及動態(tài)引入assets文件夾圖片的多種方式

    vue3+vite 動態(tài)引用靜態(tài)資源及動態(tài)引入assets文件夾圖片的多種方式

    通過require動態(tài)引入, 發(fā)現(xiàn)報錯:require is not defind,這是因為 require 是屬于 Webpack 的方法,本文給大家介紹vue3+vite 動態(tài)引用靜態(tài)資源及動態(tài)引入assets文件夾圖片的多種方式,感興趣的朋友一起看看吧
    2023-10-10
  • vue打包報錯:ERROR in static/js/xxx.js from UglifyJs undefined問題

    vue打包報錯:ERROR in static/js/xxx.js from U

    這篇文章主要介紹了vue打包報錯:ERROR in static/js/xxx.js from UglifyJs undefined問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • 淺談vuejs實現(xiàn)數(shù)據(jù)驅(qū)動視圖原理

    淺談vuejs實現(xiàn)數(shù)據(jù)驅(qū)動視圖原理

    這篇文章主要介紹了淺談vuejs實現(xiàn)數(shù)據(jù)驅(qū)動視圖原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • 詳解Vuex的屬性和作用

    詳解Vuex的屬性和作用

    這篇文章主要為大家介紹了Vuex的屬性和作用,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12

最新評論