VueJS - 跳过观察者的第一个变化
VueJS - Skip watcher's first change
我正在为我正在制作的应用程序在 VueJS 中创建一个组件,它有一些观察者在我的 var 更改时将逻辑应用于组件的其他部分。一旦组件被初始化,在用户通过 Axios 完成一些事件后,它仍然需要通过来自服务器的一些数据来设置。此数据从主应用程序发出的事件获取到组件。现在问题是这个 var 通常会改变(并非总是如此),但我不希望第一次应用该逻辑,所以我决定设置一个标志并在观察者中将其检查为 return ,但是它没有发生:一旦我将该标志设置回 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 doneFetching: false
,一旦您完成获取逻辑,您将调用 this.doneFetching = true
.
在那之后,您在观察者中所要做的就是一个干净而简单的 if(this.doneFetching){...}
这个简单的逻辑应该可以防止您的观察者逻辑在您需要之前被触发。
您可以使用实例的 $watch()
方法在组件中的任何位置开始观察数据元素。这样,观察者就不会在 Vue 实例的实例化中被实例化,正如 Docs 指定的那样:
"The Vue instance will call $watch() for each entry in the [watch] object at instantiation."
所以,您可能正在寻找这个:
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()
:它实际上是 returns 一个 "unwatch" 函数,您可以调用它来删除它 (Check it out)。
还请记住,观察者应该用于边缘情况,并避免在其他观察者内部改变观察变量。如果不小心使用,这可能会损害数据和方法之间的 Vue 反应性 "orthogonality"。
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')
}
}
}
}
我正在为我正在制作的应用程序在 VueJS 中创建一个组件,它有一些观察者在我的 var 更改时将逻辑应用于组件的其他部分。一旦组件被初始化,在用户通过 Axios 完成一些事件后,它仍然需要通过来自服务器的一些数据来设置。此数据从主应用程序发出的事件获取到组件。现在问题是这个 var 通常会改变(并非总是如此),但我不希望第一次应用该逻辑,所以我决定设置一个标志并在观察者中将其检查为 return ,但是它没有发生:一旦我将该标志设置回 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 doneFetching: false
,一旦您完成获取逻辑,您将调用 this.doneFetching = true
.
在那之后,您在观察者中所要做的就是一个干净而简单的 if(this.doneFetching){...}
这个简单的逻辑应该可以防止您的观察者逻辑在您需要之前被触发。
您可以使用实例的 $watch()
方法在组件中的任何位置开始观察数据元素。这样,观察者就不会在 Vue 实例的实例化中被实例化,正如 Docs 指定的那样:
"The Vue instance will call $watch() for each entry in the [watch] object at instantiation."
所以,您可能正在寻找这个:
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()
:它实际上是 returns 一个 "unwatch" 函数,您可以调用它来删除它 (Check it out)。
还请记住,观察者应该用于边缘情况,并避免在其他观察者内部改变观察变量。如果不小心使用,这可能会损害数据和方法之间的 Vue 反应性 "orthogonality"。
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')
}
}
}
}