web-dev-qa-db-ja.com

VueJS:なぜ「これ」が未定義なのですか?

Vue.js でコンポーネントを作成しています。

ライフサイクルフックthiscreatedmountedなど)のいずれかでupdatedを参照すると、undefinedに評価されます。

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

同じことが、計算されたプロパティ内でも発生しています。

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

次のエラーが表示されます。

不明なTypeError:未定義のプロパティ 'bar'を読み取れません

これらの場合にthisundefinedに評価されるのはなぜですか?

42
thanksd

これらの例は両方とも arrow function() => { }を使用し、Vueインスタンスとは異なるコンテキストにthisをバインドします。

ドキュメント に従って:

インスタンスプロパティまたはコールバックで矢印関数を使用しないでください(例:vm.$watch('a', newVal => this.myMethod()))。矢印関数は親コンテキストにバインドされているため、thisはVueインスタンスではなく、this.myMethodは未定義です。

Vueインスタンスとしてthisへの正しい参照を取得するには、通常の関数を使用します。

mounted: function () {
  console.log(this);
}

または、関数に ECMAScript 5の省略形 を使用することもできます。

mounted() {
  console.log(this);
}
102
thanksd

矢印関数 を使用しています。

Vue Documentation は、プロパティまたはコールバックで矢印関数を使用しないことを明記しています。

通常の関数とは異なり、矢印関数はthisをバインドしません。代わりに、thisは字句的にバインドされます(つまり、thisは元のコンテキストから意味を保持します)。

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

これにより、次のオブジェクトがコンソールに記録されます。

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

一方、...通常の関数を使用する場合(Vueインスタンスで実行する必要があります)

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

コンソールに次のオブジェクトを記録します。

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

3
Ashutosh Narang