ユアマイスターアドベントカレンダー2018の10日目の記事です。
this じゃダメ?
Vue.jsとjQueryでこんなコードを書いたとして…
<script
src="https://code.jquery.com/jquery-2.2.4.min.js"
integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.17/dist/vue.js"></script>
<div id="app">
<button @click="testFunc">
click
</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
data: 'test',
sum: 0
},
methods: {
testFunc: function () {
// 1
console.log(this);
$.each([1, 2, 3], function (i, elm) {
// 2
console.log(this);
});
}
}
})
</script>
testFunc
の中にconsole.log(this)
を2つ書きましたが、それぞれの部分で何が出てくるでしょうか?
1つ目のthis
では
Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
こんなものが出ます。
2つ目のthis
だと
Number {1}
が出力されます。
この違いなんですが、見て分かる通りVue.jsのオブジェクト
かjQueryでループしている配列の中身のオブジェクト
か、です。
vueのデータを追加したい
例えば、ループ対象の配列の値を全て加算して、それをvue側のsum
に入れたいとします。
もちろん、ループの中でvm.sum
を呼び出せばいいんですが、変数に代入しておきたくないときもあるかもしれません(少なくとも私はまだ遭遇したことないですが)。
そんな時にどうするのか、ですが、こう書きました。
<div id="app">
<button @click="testFunc">
click
</button>
</div>
<script>
var vm = new Vue({
el: '#app',
data: {
data: 'test',
sum: 0
},
methods: {
testFunc: function () {
var vueObj = this;
$.each([1, 2, 3], function (i, elm) {
vueObj.sum += elm;
});
console.log(vueObj.sum);
}
}
})
</script>
解説不要かもしれませんが、jQueryでのループ前にthis
をvueObj
として変数に入れておき、ループの中でその変数を使ってアクセスする、と言う形です。
this
を呼び出す位置によって中身が変わるのはもちろんですが、変数に入れておくことでいつでもthis(と同じオブジェクト)
を使えます。
結論
変数に入れておけ
いや当たり前かもしれないんですが、「あれどうしよう……」となる場合がありそうだなと思ったので、記事にしておきます。
jQueryからVue.jsへの移行を始めたばかりのころに起きがちではないかと思ったので、役に立てば幸いです。