国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 語言 > JavaScript > 正文

ES6 Proxy實現Vue的變化檢測問題

2024-05-06 15:38:07
字體:
來源:轉載
供稿:網友

Vue變化檢測Object使用DefineProperty、數組使用方法攔截實現。最近,Vue3.0將采用ES6 Proxy的形式重新實現Vue的變化檢測,在官方還沒給出新方法之前,我們先實現一個基于Proxy的變化檢測。

模塊劃分

參照之前Vue變化檢測的代碼,將Vue 變化檢測的功能分為以下幾個部分。

Observer Dep Watcher Utils

首先,我們要確定的問題是,將Dep依賴搜集存在哪里。Vue 2.x里,Object的依賴收集放在defineRactive,Array的依收集存入到Observer中。ES6 Proxy里,考慮到讓handler訪問dep,我們將依賴放入到Observer中。

Observer

observer.js功能代碼如下:

import Dep from './dep';import { isObject } from './utils';export default class Observer {  constructor (value) {    // 遞歸處理子元素    this.obeserve(value);    // 實現當前元素的代理    this.value = this.proxyTarget(value);  }  proxyTarget (targetBefore, keyBefore) {    const dep = new Dep();    targetBefore.__dep__ = dep;    let self = this;    const filtersAtrr = val => ['__dep__', '__parent__'].indexOf(val) > -1;    return new Proxy(targetBefore, {      get: function(target, key, receiver){        if (filtersAtrr(key)) return Reflect.get(target, key, receiver);        if (!Array.isArray(target)) {          dep.depend(key);        }        // sort/reverse等不改變數組長度的,在get里觸發        if (Array.isArray(target)) {          if ((key === 'sort' || key === 'reverse') && target.__parent__) {            target.__parent__.__dep__.notify(keyBefore);          }        }         return Reflect.get(target, key, receiver);      },      set: function(target, key, value, receiver){        if (filtersAtrr(key)) return Reflect.set(target, key, value, receiver);        // 新增元素,需要proxy        const { newValue, isChanged } = self.addProxyTarget(value, target, key, self);        // 設置key為新元素        Reflect.set(target, key, newValue, receiver);        // notify        self.depNotify(target, key, keyBefore, dep, isChanged);        return true;      },    });  }  addProxyTarget(value, target, key, self) {    let newValue = value;    let isChanged = false;    if (isObject(value) && !value.__parent__) {      self.obeserve(newValue);      newValue = self.proxyTarget(newValue, key);      newValue.__parent__ = target;      isChanged = true;    }    return {      newValue,      isChanged,    }  }  depNotify(target, key, keyBefore, dep, isChanged) {    if (isChanged && target.__parent__) {      target.__parent__.__dep__.notify(keyBefore);      return;    }    if (Array.isArray(target)) {      if (key === 'length' && target.__parent__) {        target.__parent__.__dep__.notify(keyBefore);      }    } else {      dep.notify(key);    }  }  obeserve(target) {    // 只處理對象類型,包括數組、對象    if (!isObject(target)) return;    for (let key in target) {      if (isObject(target[key]) && target[key] !== null) {        this.obeserve(target[key]);        target[key] = this.proxyTarget(target[key], key);        // 設置__parent__,方便子元素調用        target[key].__parent__ = target;      }    }  }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 隆回县| 将乐县| 长寿区| 米脂县| 太湖县| 津市市| 北碚区| 晋城| 淮滨县| 吉安县| 商水县| 绥化市| 金坛市| 南京市| 汉沽区| 桦南县| 柯坪县| 喜德县| 江北区| 碌曲县| 云浮市| 抚远县| 金堂县| 德清县| 新兴县| 澜沧| 大悟县| 句容市| 金门县| 绥江县| 溧水县| 上犹县| 桑日县| 大化| 扬中市| 宁城县| 车险| 合阳县| 香格里拉县| 花莲县| 讷河市|