原理
使用 proxy对象处理数据,添加监听,然后递归再次添加直到全部添加完毕
代码
/**
 * 给对象递归建立数据监听,可以监测每一层的每个键的变化
 * 
 * @param {*} obj // 目标对象 
 * @param {*} callback //回调。通过key处理对应的变化
 * @param {*} parentKey  递归用 不用传值
 * @returns 
 */
export default function objObserve(obj, callback, parentKey = "") {
  // 创建 Proxy 对象
  const proxy = new Proxy(obj, {
    set(target, key, value) {
      const currentKey = parentKey ? `${parentKey}.${key}` : key;
      target[key] = value;
      callback(currentKey, value);
      return true;
    }
  });
  for (const key in obj) {
    if (typeof obj[key] === "object" && obj[key] !== null) {
      obj[key] = objObserve(obj[key], callback, parentKey ? `${parentKey}.${key}` : key);
    }
  }
  // 设置一次 防止特殊环境obj类型的数据初始化不调用 (非必须)
  // activateProxy(proxy);
  return proxy;
}
const activateProxy = obj => {
  for (const key in obj) {
    if (typeof obj[key] === "object" && obj[key] !== null) {
      obj[key] = obj[key]; // 重新赋值以激活 Proxy
      activateProxy(obj[key]); // 递归处理嵌套对象
    }
  }
  return;
};
 
使用
这个方法不存在深度问题,多深都可以用,我最多用到第三层,如果更深层处有问题及时交流:}
//以对象内一个data为例 创建绑定
  constructor(data = {}) {
    super(data);
    this.data = objObserve(data, this.handler);
    ....
    ...
//绑定的回调
handler(key, value) {
    console.log(`属性 ${key} 的值被设置为 ${value}`, this);
    let firstStr = key.split(".")[0];
    switch (key) {
      case "position":
        this.position.set(...value);
        break;
      case "position.0":
        this.position.x = value;
        break;
      case "position.1":
        this.position.y = value;
        break;
      case "position.2":
        this.position.z = value;
        break;
      case "rotation":
        this.rotation.set(...value);
        break;
      case "rotation.0":
        this.rotation.x = value;
        break;
      case "rotation.1":
        this.rotation.y = value;
        break;
      case "rotation.2":
        this.rotation.z = value;
        break;
      case "scale":
        this.scale.set(...value);
        break;
      case "scale.0":
        this.scale.x = value;
        break;
      case "scale.1":
        this.scale.y = value;
        break;
      case "scale.2":
        this.scale.z = value;
        break;
      default:
        break;
    }
    if (firstStr == "config") {
      this.configHandler(key, value);
    }
  }
 
效果图
这是一个3d编辑器创建场景的输出
 



















