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

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

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

常見面試題

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

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

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

Vue 如何更新數(shù)組

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

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

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

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

// 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 為什么不能通過下標(biāo)操作數(shù)組或者改變數(shù)組的長(zhǎng)度來觸發(fā)視圖更新

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

答案:是的

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

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

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

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

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

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

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

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

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

當(dāng)然最重要的就是性能問題。

Vue 3.0 是如何處理的?

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

參考

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

相關(guān)文章

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

    Vue?Router組合布局用法詳解

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

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

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

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

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

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

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

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

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

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

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

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

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

    vue打包報(bào)錯(cuò):ERROR in static/js/xxx.js from U

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

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

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

    詳解Vuex的屬性和作用

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

最新評(píng)論