#経緯
safariでweb開発をしている際に、コンソールにthis.func() is undefinedと表示されていてなんだこれは?となった時の話です。
「methods内にfunc()はちゃんと定義してあるしなあ・・・。」と、vue初心者の僕は何がいけないのかわからず、調べてみました。
例
簡単な例を用意しました。htmlとjsは以下の通りです。
test.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="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
var app = new Vue({
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
var app = new Vue({
el: '#app',
data:{
num: 0
},
methods:{
counter: function(){
var th = this;
setInterval(function() {
th.num += 1
},1000)
}
}
})
こうすることで、thはvueインスタンスのthisを格納することになるので、numが1ずつ足されます。