VueJS: why is "this" undefined?

Viewed 55729

I'm creating a component with Vue.js.

When I reference this in any of the the lifecycle hooks (created, mounted, updated, etc.) it evaluates to undefined:

mounted: () => {
  console.log(this); // logs "undefined"
},

The same thing is also happening inside my computed properties:

computed: {
  foo: () => { 
    return this.bar + 1; 
  } 
}

I get the following error:

Uncaught TypeError: Cannot read property 'bar' of undefined

Why is this evaluating to undefined in these cases?

4 Answers

You are using arrow functions.

The Vue Documentation clearly states not to use arrow functions on a property or callback.

Unlike a regular function, an arrow function does not bind this. Instead, this is bound lexically (i.e. this keeps its meaning from its original context).

var instance = new  Vue({
    el:'#instance',
  data:{
    valueOfThis:null
  },
  created: ()=>{
    console.log(this)
  }
});

This logs the following object in the console:

Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, frames: Window, …}

Whereas... If we use a regular function (which we should on a Vue instance)

var instance = new  Vue({
    el:'#instance',
  data:{
    valueOfThis:null
  },
  created: function(){
    console.log(this)
  }
});

Logs the following object in the console:

hn {_uid: 0, _isVue: true, $options: {…}, _renderProxy: hn, _self: hn, …}

If you want to keep using the arrow function, you could pass the component instance (this) as parameter like :

computed: {
  foo: (vm) => { //vm refers to this 
    return vm.bar + 1; 
  } 
}

you cannot use the arrow funtion if you want to use the this. Because the arrow funtion doesn't bind this.

Related