Nuxt で Vue 3.0 (Composition-API) を使いたいとき
Vue3.0 がリリースされてからしばらく立ちましたが、Nuxt において Vue3.0 がサポートされた v3.0 がリリースされるのはもうちょっとかかりそうです。
とはいえ、v3.0 がリリースされるのを待って、無理やりバージョンをあげようとしてもおそらく、かなりの痛みを伴うことが、他の皆様のVue3.0移行記事からも読み取れます。
そこで、Vue 3.0 リリースより少し前から、既存の Nuxt Project に composition-API を導入した所感と、導入方法を記録しておきます。
というか、この過渡期においてNuxtへの Composition-API 導入についての日本語記事があまり見当たらなかったので、少しでも参考になれば幸いです。
なお、バージョンは記事公開時点の最新とします。
Nuxt.js v2.14.12 @nuxtjs/composition-api v0.17.0
Motivation
- Vue 3.0 (Nuxt v3) にスムーズに移行できるように準備する
- Composition-API を使いたい
- TypeScript をより使いやすくしたい
Composition-API の導入
@nuxtjs/composition-api を使います。 少し古い記事だと、@vue/composition-api を導入している記事が多いですが、@vue/composition-api のAPIは @nuxthjs/~ で全て公開されているので、今ならNuxt.js 用のものを使った方が良さそうです。また、後述しますがSSRで本格的に Composition-API を使いたい場合は、@nuxtjs/composition-api を使わないと辛いと思います。(とはいえまだRFCなので、ご利用は慎重に。。。)
各 mode 共通
$ npm install @nuxtjs/composition-api --save
{ buildModules: [ '@nuxtjs/composition-api' ] }
※ TypeScript の導入は省略
SPA の場合
Vue Composition-API の書き方で大丈夫です。Plugin や Context を使いたいときは root
をつかった方が今はいいと思います。
Nuxt 独自の非同期API である asyncData
や fetch()
についてはなるべく使わず、Vueの書き方に徹した方が、移行しやすいです。
import { defineComponent } from '@nuxtjs/composition-api' export default defineComponent ({ setup (_, { root }) { const store = root.$store const myPlugin = root.$myPlugin // 変数に代入しておけば、あとあと root を書き換えやすい } })
SSR の場合 (SSGも同様)
前述のSPAの場合ではなるべくNuxt の独自hook は使わないようにできましたが、SSRが必要な場合はそうもいきません。
@vue/composition-api
では、下記のようにキメラにするしかなかったですが、この方法だとテンプレート上の変数情報が失われてしまい、DXが悪くなります。
また、vue-meta を使う場合、setup で定義されたものにアクセスできないので、動的な変更が難しくなります。
キメラの例
import { ref } from '@nuxtjs/composition-api' export default Vue.extend ({ head () { return { title: 'タイトル' // setup 内でアクセスできないため、書き換えできない } }, async asyncData ({ app }) { const posts = await app.$http.$get('/api/posts') return { posts // setup でアクセスできない } }, setup (_, { root }) { const active = ref(false) return { active } } })
@nuxtjs/composition-api
では、従来の asyncData
, fetch()
そして head()
に変わる API が用意されています
useAsync - Nuxt Composition API
useFetch - Nuxt Composition API
useMeta - Nuxt Composition API
これらを使うことで、page component でも Composition-API を存分に使うことができますね!
ただ、時期尚早感もあるので、SSR の Pages ではComposition-APIを使わないというのも手だと思います。
半年ほど Nuxt + Composition-API を使った所感
VueとTypeScript は相性が悪いと言われていましたが、Composition-API を導入することで劇的に改善していきました。
とくに、既存のプロジェクトのUIデザイン刷新のタイミングで、Composition-API を使い、state の管理を Vuex store からどんどん移行していったところ、コードも非常にスッキリし、単一責任の原則をより意識して書く事ができるようになり、とても満足しています。
ただ、現段階での辛いところとしては、まだベストプラクティスと呼べるものが出てない(もしくは認知されてない)ので、手探りでやっていく必要があることと、自由度が高いので、プログラマーのJavaScript力やリテラシーが試されることがあります。
そういった面を踏まえて、RFCだからといって実用に耐えないかというとそんなことはなく、Nuxt v3.0のリリースも控えてますし、導入できるところはどんどん活用していって知見をためていけるといいのではないでしょうか。
別の記事で、Composition-API をつかったコンポーネント設計についても書きたいと思います。
追記: 書きました