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

關(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 對用戶來說是不可見的,他們可以在屬性被訪問和修改時通知變更。同時每個組件實例都對應(yīng)一個 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ā)訂閱,像頁面更新響應(yīng)就在這里觸發(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ù)組走不通的響應(yīng)式方案
    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方法,將屬性變成響應(yīng)式
      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)文章

  • Vue3使用hook封裝媒體查詢和事件監(jiān)聽的代碼示例

    Vue3使用hook封裝媒體查詢和事件監(jiān)聽的代碼示例

    這篇文章主要給大家詳細介紹Vue3如何使用hook封裝媒體查詢和事件監(jiān)聽,使得Vue的開發(fā)更加絲滑,文中通過代碼示例給大家介紹的非常詳細,感興趣的同學(xué)跟著小編一起來學(xué)習(xí)吧
    2023-07-07
  • vue如何實現(xiàn)拖動圖片進行排序Vue.Draggable

    vue如何實現(xiàn)拖動圖片進行排序Vue.Draggable

    這篇文章主要介紹了vue如何實現(xiàn)拖動圖片進行排序Vue.Draggable,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • VUE使用echarts?5.0以上版本渲染器未導(dǎo)入錯誤問題

    VUE使用echarts?5.0以上版本渲染器未導(dǎo)入錯誤問題

    這篇文章主要介紹了VUE使用echarts?5.0以上版本渲染器未導(dǎo)入錯誤問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • element-ui直接在表格中點擊單元格編輯

    element-ui直接在表格中點擊單元格編輯

    最近通過在網(wǎng)上查找資料,自己整合研究了一個可以直接在表格中操作數(shù)據(jù)的基于element-ui的前端模板??梢宰屧龈臄?shù)據(jù)的操作顯得方便一點,感興趣的可以了解一下
    2021-12-12
  • Vue Element前端應(yīng)用開發(fā)之界面語言國際化

    Vue Element前端應(yīng)用開發(fā)之界面語言國際化

    我們開發(fā)的系統(tǒng),一般可以不用考慮語言國際化的問題,大多數(shù)系統(tǒng)一般是給本國人使用的,而且直接使用中文開發(fā)界面會更加迅速 一些,不過框架最好能夠支持國際化的處理,以便在需要的時候,可以花點時間來實現(xiàn)多語言切換的處理,使系統(tǒng)具有更廣泛的受眾用戶。
    2021-05-05
  • vue router導(dǎo)航守衛(wèi)(router.beforeEach())的使用詳解

    vue router導(dǎo)航守衛(wèi)(router.beforeEach())的使用詳解

    導(dǎo)航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。這篇文章主要介紹了vue-router導(dǎo)航守衛(wèi)(router.beforeEach())的使用,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04
  • vue2.0實現(xiàn)點擊其他區(qū)域關(guān)閉自定義div功能

    vue2.0實現(xiàn)點擊其他區(qū)域關(guān)閉自定義div功能

    這篇文章主要介紹了vue2.0實現(xiàn)點擊其他區(qū)域關(guān)閉自定義div功能實現(xiàn),本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Vue實現(xiàn)購物車功能

    Vue實現(xiàn)購物車功能

    本篇文章主要分享了Vue實現(xiàn)購物車功能的實例代碼。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • 詳解Vue.js自定義tipOnce指令用法實例

    詳解Vue.js自定義tipOnce指令用法實例

    這篇文章主要介紹了詳解Vue.js自定義tipOnce指令用法實例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • vue框架下部署上線后刷新報404問題的解決方案(推薦)

    vue框架下部署上線后刷新報404問題的解決方案(推薦)

    這篇文章主要介紹了vue框架下部署上線后刷新報404問題解決方案,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-04-04

最新評論

蓝山县| 南岸区| 荣昌县| 岳普湖县| 蚌埠市| 繁峙县| 新建县| 博兴县| 田东县| 吴堡县| 改则县| 柳江县| 宜丰县| 田东县| 城口县| 革吉县| 弥勒县| 瑞安市| 中卫市| 石首市| 左贡县| 逊克县| 乾安县| 杭锦旗| 江源县| 隆化县| 平利县| 莫力| 洛南县| 澳门| 文水县| 南宫市| 庄河市| 北海市| 威信县| 鸡泽县| 邵东县| 遂宁市| 施秉县| 华安县| 乌兰浩特市|