Vuejs2 VueJS-跳过监视程序';第一个变化是什么

Vuejs2 VueJS-跳过监视程序';第一个变化是什么,vuejs2,vue-component,watch,Vuejs2,Vue Component,Watch,我正在为我正在制作的应用程序在VueJS中创建一个组件,它有一些观察者在我的var发生变化时将逻辑应用到组件的其他部分。组件初始化后,仍然需要通过用户通过Axios完成一些事件后来自服务器的一些数据进行设置。此数据通过主应用程序引发的事件到达组件。现在的问题是这个变量通常会改变(不总是),但我不想第一次应用这个逻辑,所以我决定设置一个标志并在观察程序中检查它以返回,但它没有发生:只要我将该标志设置回true(它检查!this.flag),观察程序就会被触发。代码如下: data(){ r

我正在为我正在制作的应用程序在VueJS中创建一个组件,它有一些观察者在我的var发生变化时将逻辑应用到组件的其他部分。组件初始化后,仍然需要通过用户通过Axios完成一些事件后来自服务器的一些数据进行设置。此数据通过主应用程序引发的事件到达组件。现在的问题是这个变量通常会改变(不总是),但我不想第一次应用这个逻辑,所以我决定设置一个标志并在观察程序中检查它以返回,但它没有发生:只要我将该标志设置回true(它检查!this.flag),观察程序就会被触发。代码如下:

data(){
    return {
        isSet: false,
        myVar: {
            first: 0,
            second: 0
        }
    }
},
watch: {
    'myVar.first': {
        handler: function(newVal, oldVal){
            if(!this.isSet || other.condition){return}
            console.log('first triggered');
        },
        immediate: false
    },
    'myVar.second': {
        handler: function(newVal, oldVal){
            if(!this.isSet || other.condition){return}
                console.log('second triggered');
        },
        immediate: false
    }
},
methods: {
    setBus(){ // gets called on created(){}
        let self = this;
        Bus.$on('my-event', function(c){
            self.doFirstSet(c);
        });
    },
    doFirstSet(c){
        // do other setting
        if(c.someCondition){
            this.doExtraConfig(c);
        }
        this.isSet = true; // at this point is when the watchers get triggered
    },
    doExtraConfig(c){
        // do more stuff
        if('first' in c){
            this.myVar.first = c.first;
        }else if('second' in c){
            this.myVar.second = c.second;
        }
        console.log("watchers don't get triggered yet");
    }
}

您知道如何在标志更改时阻止它们触发吗?

您只需声明一个布尔变量,该变量定义数据提取是否完成。 默认情况下,您将其设置为false
donefetch:false
,一旦抓取逻辑完成,您将调用
this.donefetch=true

在这之后,您在watcher中所要做的就是一个干净且简单的
if(this.doneFetching){…}

这个简单的逻辑应该可以防止您的监视程序逻辑在您需要它之前被触发。

您可以使用实例的
$watch()
方法在组件中的任意点开始监视数据元素。这样,观察者就不会在Vue实例的实例化上被实例化,具体如下:

Vue实例将在实例化时为[watch]对象中的每个条目调用$watch()。

所以,你可能会在寻找这个:

data: {
  return() {
    data: null,
  };
},

mounted() {
  api.fetchList().then((response) => {
    this.data = response.dataFetched
    this.$watch('data', this.dataWatcher);
  });
},

methods: {
  dataWatcher() {
    // Code won't execute after this.data assignment at the api promise resolution
  },
}
在这种简单的情况下,Badgy的响应更直接,尽管您可以避免使用
donefetch
变量。如果需要更多的控制,我会使用
$watch()
:它实际上返回一个“unwatch”函数,您可以调用它来删除它()


还请记住,应该在边缘情况下使用观察者,并避免在其他观察者内部变异被观察的变量。如果不小心使用,这可能会损害Vue反应性在数据和方法之间的“正交性”。

Badgy的反应似乎不那么具有侵入性,也不太容易出错

我们项目中使用的经过战斗验证的方法,特别是用于跟踪更改的方法,如下所示:

export default {
  data: () => {
    dataLoaded: false,
    valueThatChanges: 'defaultValue',
  },
  mounted () {
    let self = this
    loadData().then((result) => {
      self.valueThatChanges = result
      self.$nextTick(() => { //with this we skip the first change
        self.dataLoaded = true
      })
    })
  },
  methods: {
    loadData() {
      //your implementation
      return result
    }
  },
  watch: {
    valueThatChanges: function(newValue, oldValue) {
      if (this.dataLoaded) {
        //send tracking change
        console.log('Value was changed from ' + oldValue + ' to ' + newValue + ' via interaction, not by loading')
      }
    }
  }
}

这比使用布尔值要好,因为在更改布尔值后可以异步调用watch回调。我同意@yooouuri的观点,并给这个答案的作者带来了一些帮助。:-)我认为没有必要使用
let self=this
。箭头函数从外部范围保留
的值。