Reputation: 165182
Given this Vue component that attaches a global event listener:
var app = new Vue({
data: {
foo: 0;
},
methods: {
handle: function(e) {
this.foo = 1; // this refers to handler, not app
}
},
mounted: function() {
window.addEventListener("keypress", this.handle);
}
});
What is the correct way to refer to this
from within the event handler in order to update the component state? Alternatively, is there a better way to set event handlers on the entire window
?
Upvotes: 10
Views: 3466
Reputation: 858
Your data property should be a function, not an object.
data(){
return {
foo: 1
}
}
Upvotes: 0
Reputation: 14904
Actually this
is binded to the vue instance and your code works fine.
var app = new Vue({
el: "#app",
data: {
foo: 0
},
methods: {
handle: function(e) {
this.foo++;
console.log(this.foo);
}
},
mounted: function() {
window.addEventListener("keypress", this.handle);
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
{{ foo }}
</div>
The common mistake is if you have for example an function with an callback and you try to use this
inside the callback, it will be undefined
handle: function(e) {
this.foo++;
setTimeout(function(){
console.log(this.foo); //undefined
})
console.log(this.foo);
}
You could either use arrow functions
handle: function(e) {
this.foo++;
setTimeout(() =>{
console.log(this.foo);
})
console.log(this.foo);
}
},
Or if its need to be backwards compatible you could use .bind()
handle: function(e) {
this.foo++;
setTimeout(function(){
console.log(this.foo);
}.bind(this))
console.log(this.foo);
}
},
Upvotes: 7