国产探花免费观看_亚洲丰满少妇自慰呻吟_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;      }    }  }}            
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

主站蜘蛛池模板: 崇礼县| 沅江市| 嘉定区| 闻喜县| 马关县| 象山县| 北流市| 铅山县| 阿克苏市| 曲靖市| 巴楚县| 兴海县| 山东| 隆子县| 莱阳市| 刚察县| 惠安县| 汾阳市| 汉阴县| 鲁山县| 武夷山市| 历史| 宝应县| 贞丰县| 望城县| 岳西县| 合作市| 清水河县| 广州市| 宜兴市| 株洲市| 三原县| 罗江县| 云南省| 炉霍县| 合江县| 赞皇县| 皋兰县| 西城区| 黑水县| 永德县|