経緯
safariでweb開発をしている際に、コンソールにthis.func() is undefinedと表示されていてなんだこれは?となった時の話です。
「methods内にfunc()はちゃんと定義してあるしなあ・・・。」と、vue初心者の僕は何がいけないのかわからず、調べてみました。
例
簡単な例を用意しました。htmlとjsは以下の通りです。
test.html
<!DOCTYPE html><html><head><metacharset="utf-8"></head><body><divid="app"><button@click="counter">クリック!</button>
{{ num }}
</div><script src="https://cdn.jsdelivr.net/npm/vue"></script><script src="test.js"></script></body></html>
test.js
varapp=newVue({el:'#app',data:{num:0},methods:{counter:function(){setInterval(function(){this.num+=1},1000)}}})
ボタンをクリックすると、ボタンの横の「0」が1秒ごとに1,2,3・・・と増えていきます(実際はエラーが出ます)
何がいけないのか
counter関数内の"this"が原因です。
このthisは、vueインスタンスのthisではなく、setIntervalのthis(window?)を指してしまっています。
対策
setInterval()を呼び出す前に、var th = this;というように記述しましょう。
変更後のjsファイルは以下のようになります。
test.js
varapp=newVue({el:'#app',data:{num:0},methods:{counter:function(){varth=this;setInterval(function(){th.num+=1},1000)}}})
こうすることで、thはvueインスタンスのthisを格納することになるので、numが1ずつ足されます。