methods
, computed
等の中の関数をアロー関数(アローファンクション)にしてはいけない。
vueのバージョン 2.6.11
※vueのバージョン確認はnpm list vue
vue.cliは 4.2.3
データにアクセスしようとするとundefined
になる不具合
次のコードは問題ない。
data
部の外側の定義はアローファンクションを使っても良い。これが混乱を招く。
export default {
data: () => ({ //アローファンクションで定義
message_data: "ok"
}),
methods: {
test() {
console.log(this.message_data)
}
},
// 実行結果
// ok
アロー関数とはES6から実装された文法でここではメソッドの定義に使用している。
data: function(){}
とするところを data: () => {}
と記述してよい。
ES6にてオブジェクトにメソッドを割り当てる場合アローファンクションを使っても良いというのを経験上知っている。ただ、JS公式の「メソッド定義」にはこの方法は書いていないのでもしかしたら間違っているのだろうか。
Node.jsにて次のコードが正しく動作することを検証した。
//es6を使うので拡張子はmjs
const A = {
tes_string: "ok",
myFunc: () => { //ここがアロー関数
console.log(A.tes_string)
}
}
A.myFunc()
// 実行結果
// ok
Vue.jsにて。次のコードはビルドエラーにはならないが実行時にエラーとなる。
export default {
data: () => ({
message_data: "ok"
}),
methods: {
test() {
console.log(this.testComputed) //computed越しにmessage_dataを表示
}
},
computed: {
testComputed:() => { //問題のコード。アロー関数で定義されている
return this.message_data
}
}
}
//実行結果
//TypeError: Cannot read property 'message_data' of undefined
これはコンパイル時にはエラーにならない。
私はこの問題に悩まされたが次のフォーラムにたどり着いて解決した
英語:VueJS: variable is undefined inside computed only
念の為正しいコードを提示する。
<script>
export default {
data: () => ({
message_data: "ok"
}),
methods: {
test() {
console.log(this.testComputed)
}
},
computed: {
testComputed(){ //ここを修正
return this.message_data
}
}
}
</script>
// 実行結果
// ok
Don't use arrow function ()=>{} for computed, it will cause the wrong context (not current Vue instance).
Change to function () {} then it should work fine.
And for methods, watch, you should follow same rules.
先程のフォーラムの指摘箇所原文。強調した箇所によるとmethods
やwatch
などでも同様のことが言えるらしい。
今までこの問題にぶち当たらなかったのはmethods
やcomputed
内では キー名: function()
~~ ではなく 関数名()
でいきなり書き始められるからだ。これはNode.jsも同様で正しく動作する。
methods: {
test() { //これで良い
console.log(this.testComputed)
}
}
Vue.jsの公式コードがこの部分をキーと値の書式で記述している。これによりドキュメントを何気に参照したのち手癖でアローファンクションにしてしまった。
次が公式の書式
methods: {
reverseMessage: function () {
return this.message.split('').reverse().join('')
}
}
//アローファンクションではないが : を使ってキー名:値のような書式になっている
//当然 reverseMessage: () => { でも動作すると考えてもおかしくない
Vue.jsのデメリットではあるが加えてJavaScriptのデメリットに出会った気がする。定義方法が曖昧だ。
今の所予定はないがGitHub最近はReactも学習して良いかなと考え始めた。
npmtrends.comによるVue.jsとReact.jsのDL数比較を参考に出しておく。
スター数ではVueに軍配があがるが、DL数で見るとReactの伸びが圧倒的になっている。