使用 Proxy | Reflect 做数据劫持 | 全局数据监听

Posted liujinyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 Proxy | Reflect 做数据劫持 | 全局数据监听相关的知识,希望对你有一定的参考价值。

使用demo

import globalData from ./globalData

const {userInfo} = globalData
userInfo.watch(name,str=>{
    console.log(My name is:,str)
})
userInfo.name = liujinyu

 

globalData.js

import _event from "./event";

const validator = {
  set: function (target, prop, value) {
    target.emit(prop, value);
    return Reflect.set(...arguments);
  },
  get: function () {
    return Reflect.get(...arguments);
  },
};
const creat = (defaultData = {}) => {
  return new Proxy(
    Object.assign(Object.create(_event), defaultData),
    validator
  );
};

const globalData = {
  userInfo: creat({}),
};

export default globalData;

 

event.js

function Events() {
    // 放置所有添加的 监听事件
    this._events = {};
}
Events.prototype = {
    on: function (name, fn, ...argOrg) {
        // 必传参数验证
        if (!name || !fn) {
            throw new Error(`[Events TypeError] Failed to execute Events on ${name} : 2 arguments required`);
        }
        // 阻止重复添加相同的监听
        let fns = this._events[name] || [];
        if (fns.find((item) => item.fnOrg === fn)) {
            return;
        }
        this._events[name] = fns.concat({
            fn: (arg) => fn.apply(null, [...argOrg, ...arg]),
            fnOrg: fn
        });
    },
    watch() {
        this.on(...arguments);
    },
    once: function (name, fn, ...argOrg) {
        const onFn = (...arg) => {
            fn.apply(null, arg);
            this.off(name, onFn);
        };
        this.on(name, onFn, ...argOrg);
    },
    emit: function (name, ...arg) {
        (this._events[name] || []).forEach((item) => {
            item.fn(arg);
        });
    },
    off: function (name, fn) {
        // 无参数 : 清掉所有监听
        if (!arguments.length) {
            this._events = Object.create(null);
        }
        // 一个参数 : 清掉该事件名下所有监听
        if (arguments.length == 1) {
            delete this._events[name];
        }
        let fns = this._events[name];
        if (!fns || !fns.length) return;
        this._events[name] = (fns || []).filter((item) => {
            return item.fnOrg !== fn;
        });
    }
};
export default new Events();

源代码地址:https://github.com/liujinyu1029/util-bar/blob/master/importType/globalData.js

demo地址:https://github.com/liujinyu1029/util-bar/blob/master/demo/globalData.html

以上是关于使用 Proxy | Reflect 做数据劫持 | 全局数据监听的主要内容,如果未能解决你的问题,请参考以下文章

Vue3.0底层原理详解

Vue源码Object.defineProperty与Proxy

利用ES6中的Proxy和Reflect 实现简单的双向数据绑定

敲黑板,划重点!!!Vue3.0响应式实现原理 —— proxy()

敲黑板,划重点!!!Vue3.0响应式实现原理 —— proxy()

敲黑板,划重点!!!Vue3.0响应式实现原理 —— proxy()