91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

vue2和vue3數據響應式原理分析及如何實現

發布時間:2021-12-22 20:22:07 來源:億速云 閱讀:176 作者:柒染 欄目:編程語言

今天就跟大家聊聊有關vue2和vue3數據響應式原理分析及如何實現,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

數據響應式

  • 視圖跟數據是自動更新的,數據更新的時候視圖是自動的更新的

  • 追蹤數據的變化,在讀取數據或者設置數據的時候能夠做一些劫持的一些操作

  • vue2 使用defineProperty

  • vue3 改用Proxy

使用defineProperty

如何追蹤變化

var obj = {}var age 
Object.defineProperty(obj, 'age', {
    get: function() {
        consoel.log('get age ...')
        return age    },
    set: function(val) {
        console.log('set age ...')
        age = val    }})obj.age =100 //set age ...console.log(obj.age)//get age ...

對象obj在取age屬性的時候會調用數據劫持的get方法
在給age屬性賦值的時候會調用set方法

那怎么使用Object.defineProperty實現一個數據響應式呢

function defineReactive(data) {
  if (!data || Object.prototype.toString.call(data) !== '[object Object]')
    return;
  for (let key in data) {
    let val = data[key];
    Object.defineProperty(data, key, {
      enumerable: true, //可枚舉
      configurable: true, //可配置
      get: function() {
        track(data, key);
        return val;
      },
      set: function() {
        trigger(val, key);
      },
    });
    if (typeof val === "object") {
      defineReactive(val);
    }
  }}function trigger(val, key) {
  console.log("sue set", val, key);}function track(val, key) {
  console.log("sue set", val, key);}const data = {
  name:'better',
  firends:['1','2']}defineReactive(data)console.log(data.name)console.log(data.firends[1])console.log(data.firends[0])console.log(Object.prototype.toString.call(data))

這個函數defineReactve用來對Object.defineProperty進行封裝,從函數名可以看出,起作用就是定義一個響應式數據,封裝后只需要傳遞data,key和val就行
每當從data中讀取key的時候觸發track函數,往data的key中設置數據時,set函數中的trigger函數觸發

數組的響應式

我們通過Array原型上的方法來改變數組的內容不會觸發getter和setter
整理發現Array原型中可以改變數組自身內容的方法有7個,分別push pop shift unshift splice sort reverse
vue2 改寫了這這7種方法
實現方式:
以Array.propertype為原型創建一個arrayMethods對象,再使用Object.setPropertypeOf(o, arryMethods)將o的__proto__指向arrayMethods

vue2和vue3數據響應式原理分析及如何實現

如何收集依賴

使用

<template><p>{{name}}</p></template>

該模板中使用數據 name, 我們要觀察數據, 當數據的屬性發生變化的時候, 可以通知哪些使用的地方,
這就是我們要先收集依賴,即把用到數據name的地方收集起來,然后等數據變化的時候,把之前收集好的依賴循環觸發一遍,總結來說就是getter中收集依賴,在setter中觸發依賴

使用proxy

Proxy對象用于創建一個對象的代理, 從而實現基本操作的攔截和定義(如屬性查找、賦值、枚舉、函數掉用等)

const p = new Proxy(target, handler)
  • target

  • 要使用 Proxy 包裝的目標對象(可以是任何類型的對象,包括原生數組,函數,甚至另一個代理)。

  • handler

  • 一個通常以函數作為屬性的對象,各屬性中的函數分別定義了在執行各種操作時代理 p 的行為。
    reflect是一個內置對象, 他提供攔截javascript操作的方法, 這些方法和Proxy handlers相同

Reflect.set將值分配給屬性的函數。返回一個Boolean 如果更新成功則返回true

Reflect.get獲取對象身上某個屬性的值,類似target[name]

如何實現劫持

const dinner = {
  meal:'111'}const handler = {
  get(target, prop) {
    console.log('get...', prop)
    return Reflect.get(...arguments)
  },
  set(target, key, value) {
    console.log('get...', prop)
    console.log('set',key,value)
    return Reflect.set(...arguments)
  }}const proxy = new Proxy(dinner, handler)console.log(proxy.meal)console.log(proxy.meal)

代碼中dinner 對象代理到handler上
defineProperty區別
defineProperty的屬性需要遍歷才能監管所有屬性

使用proxy可以將對象所有屬性進行代理

用proxy實現一個模擬響應式

function reactive(obj) {
  const handler = {
    get(target, prop, receiver) {
      track(target, prop);
      const value =  Reflect.get(...arguments);
      if(typeof value === 'Object') {
        reactive(value)
      }else {
        return value      }
    },
    set(target,key, value, receiver) {
      trigger(target,key, value);
      return Reflect.set(...arguments);
    },
  };
  return new Proxy(obj,handler)}function track(data, key) {
  console.log("sue set", data, key);}function trigger(data, key,value) {
  console.log("sue set", key,':',value);}const dinner = {
  name:'haochi1'}const proxy  =reactive(dinner)proxy.name
proxy.list = []proxy.list.push(1)

執行后自動打印

vue2和vue3數據響應式原理分析及如何實現

思考:為啥只在get中使用遞歸,set不使用呢?

賦值也需要先get

簡單總結:

  1. vue2 (淺響應式)

  • 遍歷data,使用defineProperty攔截所有屬性

  • 當用戶操作視圖,會觸發set攔截器

  • set先改變當前數據, 再通知wartch, 讓watch去通知視圖更新

  • 視圖重繪, 再次從get中獲取對應的數據

  1. vue3 (深度響應式) :

  • 使用proxy 進行代理;攔截data任意屬性的任意操作(13種), 包括屬性的讀寫, 屬性的添加, 屬性的刪除等等

  • 使用Reflect進行反射; 動態對被代理的對象的相應屬性進行特定的操作

  • 代理對象(proxy)的反射對象(reflect)必須相互配合才能實現響應式

兩者的不同

Proxy能劫持整個對象,而Object.defineProperty只能劫持對象的屬性; 前者遞歸返回屬性對應的值的代理即可實現響應式,后者需要深度遍歷每個屬性,后者對數組的操作很不友好.

看完上述內容,你們對vue2和vue3數據響應式原理分析及如何實現有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

vue
AI

崇信县| 昌图县| 阿克苏市| 湄潭县| 八宿县| 元谋县| 屏山县| 平果县| 启东市| 曲麻莱县| 舞阳县| 宣武区| 黄石市| 新乐市| 九龙县| 科技| 大连市| 海南省| 蒲城县| 武乡县| 巴林右旗| 永丰县| 南阳市| 洪湖市| 新化县| 宾阳县| 平邑县| 山东省| 武义县| 武强县| 宁陕县| 青州市| 涟水县| 志丹县| 安徽省| 金阳县| 永康市| 马关县| 鄱阳县| 青海省| 鄂伦春自治旗|