Pab*_*lba 2 watch vue-component vuejs2
我正在VueJS中为正在制作的应用程序创建组件,当var更改时,它具有一些监视程序,可将逻辑应用于组件的其他部分。一旦组件被初始化,在用户通过Axios完成一些事件之后,仍然需要服务器上的一些数据来设置它。这些数据从主应用程序发出的事件到达组件。现在的事情是,此var通常会更改(并非总是更改),但是我不希望第一次应用该逻辑,因此我决定设置一个标志并在watcher中检查它是否返回,但是这没有发生:一旦将该标志设置为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");
}
}
Run Code Online (Sandbox Code Playgroud)
有什么想法如何在标志更改时阻止他们开火?
小智 28
您可以使用实例的$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
},
}
Run Code Online (Sandbox Code Playgroud)
在像这样的简单情况下,Badgy 的反应更加直接,尽管您可以避免该doneFetching变量。$watch()如果我需要更多控制,我会使用它:它实际上返回一个“unwatch”函数,你可以调用它来删除它(检查出来)。
还要记住,观察者应该用于边缘情况,并避免在其他观察者中改变观察到的变量。如果不小心使用,这可能会损害 Vue 反应性在数据和方法之间的“正交性”。
小智 15
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')
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
您应该只声明一个布尔变量,该变量定义是否完成了数据提取。默认情况下,将其设置为false doneFetching: false,一旦完成提取逻辑,就调用this.doneFetching = true。
之后,您在观察器中所要做的只是if(this.doneFetching){...}
简单而干净的。此简单的逻辑应该可以防止在需要之前触发观察器逻辑。
| 归档时间: |
|
| 查看次数: |
1959 次 |
| 最近记录: |