Vue.js 监视事件中的嵌套属性

Vue.js 监视事件中的嵌套属性,vue.js,vuejs2,Vue.js,Vuejs2,我知道我的问题可能是重复的,但我在任何地方都找不到问题的答案 我有一个带有一些键/值的对象,我想观察所有属性中的变化,记住所有属性在我的对象中都必须有单独的事件 data: () => ({ filters: { All: false, AllUSA: false, AllSouthAmerica: false, AllAsia: false, AllEurope: false } }), 观

我知道我的问题可能是重复的,但我在任何地方都找不到问题的答案 我有一个带有一些键/值的对象,我想观察所有属性中的变化,记住所有属性在我的对象中都必须有单独的事件

data: () => ({
    filters: {
        All: false,
        AllUSA: false,
        AllSouthAmerica: false,
        AllAsia: false,
        AllEurope: false
    }
}),
观看

 watch: {
    "filters.All": function(val) {
        if (val) {
            this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
                [k]: true
            })));
            this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
                [k]: true
            })));
        } else {
            this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
                [k]: false
            })));
            this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
                [k]: false
            })));
        }
    },
    "filters.AllUSA": function(val) {
        alert("both event being called")
        this.TrafficSource = Object.assign(...Object.keys(this.TrafficSource).map(k => ({
            [k]: false
        })));
        this.filters = Object.assign(...Object.keys(this.filters).map(k => ({
            [k]: false
        })));

        if (val) {
            this.TrafficSource.Virginia = true;
            this.TrafficSource.California = true;
            this.TrafficSource.Oregon = true;
        } else {
            this.TrafficSource.Virginia = false;
            this.TrafficSource.California = false;
            this.TrafficSource.Oregon = false;
        }

    },
    deep: true
  }

现在的问题是,通过
过滤器,两个监视事件都被称为事件。所有的
都被调用了,我做错了什么?

您可以使用具有如下过滤器选项的监视程序:

watch: {
  filters: {
     immediate: true,
     deep: true,
     handler(newValue, oldValue) {
     // you can write code to tell you which property is changed since you have
       access to the old and new value here
    }
  },
};
// all of this code should be done in the watcher's handler
const newVals = Object.values(newValue);
const oldVals = Object.values(oldValue);
const changedVal = [];
newVals.forEach((x, i) => {
  if (x !== oldVals[i]) {
    const result = Object.entries(newValue).filter(y => y[1] === x).flat();
    changedVal.push(result[0]);
  }
});
当您的组件加载时,这种监视程序会立即运行,因为它具有
deep:true
,如果其监视的对象中的任何属性发生更改,它将触发

现在,为了让代码跟踪实际更改的内容,您可以编写如下内容:

watch: {
  filters: {
     immediate: true,
     deep: true,
     handler(newValue, oldValue) {
     // you can write code to tell you which property is changed since you have
       access to the old and new value here
    }
  },
};
// all of this code should be done in the watcher's handler
const newVals = Object.values(newValue);
const oldVals = Object.values(oldValue);
const changedVal = [];
newVals.forEach((x, i) => {
  if (x !== oldVals[i]) {
    const result = Object.entries(newValue).filter(y => y[1] === x).flat();
    changedVal.push(result[0]);
  }
});
现在,您在
处理程序中的
changedVal
数组中拥有了所有已更改的
,您可以继续在
处理程序中执行逻辑


编辑:我也不认为
changedVal
应该是一个数组,您可以将它设置为已更改的
,然后根据该

您正在分配的
这个。过滤器
内部
过滤器。所有
观察者。这会触发filters.AllUSA上的观察者。我很惊讶你没有得到一个无限循环。作为旁注,您不应该过度使用
Object.assign()
,我也不想在数组中使用它,因为在很多情况下它可能不会产生预期的结果。此外,这会使您的代码很难遵循/调试,这正是您必须提出问题的原因。这是一个很好的问题,在我的情况下,问题是我选择/取消选择了这些过滤器基本上都是复选框,这不是像您这样使用
Object.assign
的原因。如果您愿意创建一个(如果您需要一个类似节点的多文件编辑器,请使用codesandbox.io),我会看一看,可能会想出一种更简单的方法。而且更容易掌握/遵循/调试。就我而言,你甚至不应该为此需要观察者。这一切都可以通过使用setter/getter进行计算来完成。