Vueのfilters
でthis
が使えなかった話
Vue.jsのfiltersで↓のようなコードを書いて実行しようとしたらエラーがでた。
最初はMixinとして使っていたためMixinではfilters
は使えないのかと思い、普通にコンポーネント内のfilters
プロパティ内で使っても同じエラーがでたので調べることにした。
ちなみにfilters
というのはVue固有のプロパティの一つで、ここに定義した関数をムスタッシュ構文内で例えば{{ <data> | oneFilter }}
のようにして使うと<data>
をoneFilter
で加工することができる。
<template>
<div id="app">
<p>{{ '選択してください' | processChoice }}</p>
</div>
</template>
<script>
new Vue({
el: '#app',
computed: {
getName (obj) {
if (obj) {
return obj.name
}
}
},
filters: {
processChoice(value) {
if (this.getName) {
return this.getName
}
return value
}
}
})
</script>
Cannot read property 'getName' of undefined...
結論
先に結論を書いてしまうと、**「Vueのfilters
プロパティではthis
(Vueインスタンス)にはアクセスできないようなので、computed
かmethods
を使いましょう」**ということらしいです。
filters
で定義した関数内からthis
にアクセスできないので、undefined
エラーが出ているということですね。
調べたこととか
1番目のリンクのissueに対する回答で、Evan You(Vue.jsの作者)がfiltersでは敢えてVueインスタンスにアクセスできないようににしていると言っています。filtersでは純粋なJSの関数を使うことしか現状できないようです。どうしてもthis
を使う必要がある時は結論に書いたようにfilters
ではなく、computed
かmethods
に処理をまとめて書いてそれを使いましょう。(compoted
とmethods
もムスタッシュ構文に埋め込むことが可能です。)
何人かの開発者がfilters内でthis
を使えるようにして欲しいと書いていますが、
作者が↓のように言っているのでVue3系でも同じ仕様になるような気がします。
I'm absolutely convinced that filters must have a way access the context. The question's what core team is going to do about it?
Sorry but my opinion has not changed: filters should not, and will not have access to context. If you need context, use a method.