VueJS - 跳过观察者的第一个更改



我正在为我正在制作的应用程序在 VueJS 中创建一个组件,它有一些观察者可以在我的 var 更改时将逻辑应用于组件的其他部分。初始化组件后,它仍然需要由用户通过 Axios 完成一些事件后来自服务器的一些数据进行设置。此数据从主应用发出的事件获取到组件。现在问题是这个 var 通常会改变(并非总是如此(,但我不希望第一次应用该逻辑,所以我决定设置一个标志并在观察器中检查它以返回,但它没有发生:一旦我将该标志设置回 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");
}
}

知道如何在旗帜变化时阻止他们开火吗?

您可以使用实例的$watch()方法在组件中的任何点开始监视数据元素。这样,观察者就不会直接在 Vue 实例的实例化上实例化,正如 Docs 所指定的那样:

">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 的响应更直接,尽管你可以避免doneFetching变量。如果我需要更多的控制,我会使用该$watch():它实际上返回一个"取消监视"函数,您可以调用它来删除它(检查一下(。

还要记住,观察程序应该用于边缘情况,并避免改变其他观察程序内部的监视变量。如果不谨慎使用,这可能会损害 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')
}
}
}
}

您应该简单地声明一个布尔变量,该变量定义您的数据获取是否完成。 默认情况下,您将其设置为 falsedoneFetching: false,一旦获取逻辑完成,您就会调用this.doneFetching = true

之后,您在观察器中所要做的就是一个干净而简单的if(this.doneFetching){...}这个简单的逻辑应该可以防止观察程序逻辑在你想要之前被触发。

最新更新