使用on-change 模块 监听对象变化

542 阅读2分钟

on-change提供了一个简单的监听对象(Object)或数组(Array)的属性变化,on-change可以监听任务深度的属性变化,如obj.a.b[0].c = true

安装

$ npm isntall -S on-change
# 或者
$ yarn add on-change

基本用法

// 创建一个需要监听的对象
    const object = {
        foo: false,
        a: {
            b: [
                {
                    c: false
                }
            ]
        }
    };


// 此处返回一个监听对象
const watchedObject = onChange(object, function (path, value, previousValue) {
    console.log('this:', this);  // Proxy {foo: true, a: {…}}
    console.log('path:', path);	 // path: a.b.0.c
    console.log('value:', value);  // value: true
    console.log('previousValue:', previousValue);  // previousValue: false
});

// 我们现在改变任意的属性的值, 将会触发回调,输出如上注释
watchedObject.a.b[0].c = true;

参数及方法

onChange方法的参数

onChange(object, onChange, options?)

被监听的返回对象与原对象一样,只是添加了代理

参数1: object

必传,需要被监听对象,可以是object也可以是array

参数2: 回调函数onChange

该函数会在被监听对象属性发生改变时调用,回调函数接受三个参数

  1. path :已更改值的路径,如上a.b.0.c
  2. value:在此路径上,新的值
  3. previousValue:此路径上,上一次的值

例如:

const watchedObject = onChange(object, function (path, value, previousValue) {
    console.log('this:', this);  // 这里的 this 指向代理对象
    console.log('path:', path);	 // 已经个更改值的路径
    console.log('value:', value);  // 此路径上的新值
    console.log('previousValue:', previousValue);  // 此路径上,上一次的值
});

参数3: options?

  • isShallow:boolean类型,默认值为false,如果设置为true,深度属性改变不会触发回调,只有改变原始对象直接属性才会触发回调;
  • equals:接受一个函数,默认为Object.is,接受两个参数就行比较,如果相等返回true,如果需要更宽松的比较方式,可以设置这个参数
  • ignoreSymbols:设置Symbo类型的属性是否不处罚回调,默认为false; 设置为true,则不触发回调
  • ignoreKeys:Array<string | symbol> 数组类型,此数组内的属性值修改不会触发回调
  • ignoreUnderscores:忽略下滑线的属性,默认为false
  • pathAsArray:boolean,默认为fasle,输出为a.b.0.c 这种形式,设置为true,则路径用数组表示

onChange.target(object)

​ 返回未监听原始对象

onChange.unsubscribe(object)

​ 取消被监听对象的所有回调,并返回原始对象

例子

有些代码可能如下,每次改变属性需要保存修改的对象

const foo = {
	a: 0,
	b: 0
};

// …

foo.a = 3;
save(foo); // 保存对象,或者其他操作

// …

foo.b = 7;
save(foo); // 保存对象,或者其他操作


// …

foo.a = 10;
save(foo); // 保存对象,或者其他操作

现在使用on-change就可以简化如下代码

const foo = onChange({
	a: 0,
	b: 0
}, () => save(foo));

// …

foo.a = 3;

// …

foo.b = 7;

// …

foo.a = 10;