nuxtjs/composition-api の意外な利点と使い方

公開:2021/02/15
更新:2021/02/15
3 min読了の目安(約2700字TECH技術記事

はじめに

composition-apiがリリースされて時間が経ちました。

Nuxt.jsで使う場合はpluginsで
Vue.use(VueCompositionApi)
を読み込むやり方が主流だったのではと思います。

そんな中、 @nuxtjs/composition-api がリリースされていました。
@vue/composition-apiと比べてNuxt特有の機能(UseAsync)などをサポートしているのが特色で、@vue/composition-apiをラップしているのでcomposition-apiの機能はもちろんNuxt特有の機能が揃っている。というものです。
なのですが個人的には以下の1点のみが気に入ってます。

- Easy access to router, app, store within setup()

@vue/composition-apiのPlugin版と比べて何が良いのか見ていきます。

なにが違うのか

route.params.id の取得方法

@vue/composition-apiの場合

// index.vue
export default defineComponent({
  setup(_, context) {
    console.log(context.root.$route.params.id)
    return {}
  }
})

@nuxtjs/composition-apiの場合

// index.vue
import { useContext } from '@nuxtjs/composition-api'

export default defineComponent({
  setup() {
    const { route } = useContext()
    console.log(route.params.id)
    return {}
  }
})

ここまでだとちょっと書き方が変わったレベルですね。

route.params.id を外部に切り出した関数で使いたい場合

composition-apiの特徴はデータ、処理を分けられることにあります。
composables, use, などのディレクトリを切ってロジック処理を外に書くのはよくあると思います。
その切り出した処理の中でroute.params.idを使いたい場合を見てみましょう。

@vue/composition-apiの場合

// useHoge.ts
const useHoge = (context) => {
  console.log(context.root.$route.params.id)
}
export default useHoge

// index.vue
export default defineComponent({
  setup(_, context) {
    useHoge(context)
    return {}
  }
})

@nuxtjs/composition-apiの場合

// useHoge.ts
import { useContext } from '@nuxtjs/composition-api'
const useHoge = () => {
  const { route } = useContext()
  console.log(route.params.id)
}
export default useHoge

// index.vue
export default defineComponent({
  setup(_, context) {
    useHoge()
    return {}
  }
})

はい、利点が見えてきました。
@vue/composition-api では呼び出し時にcontextを引数として渡す
@nuxtjs/composition-api では呼び出された場所のcontextをuseContextで取得できる

contextをリレーする必要がなくなります。

テストしたい

pureJSのテストをしたい場合、useContextで値を取得する処理だとそのままではundefindになります。

まず、 jestの設定 を行います。

jest実行時にcontextの値を注入します。


import { shallowMount } from '@vue/test-utils'
import XXX from '../XXX.vue'

test('xxx', () => {
  const wrapper = shallowMount(XXX, {
    mocks: { // 注入
      $route: {
        params: {
          id: 1,
        },
      },
    },
  })
  // ...
})

これでjest実行時に

const { route } = useContext()
console.log(route.params.id) // 1

という処理では注入した 1 が取得、表示できます

参考

さいごに

@nuxtjs/composition-apiは
@vue/composition-api と同じ機能が使えてNuxt特有の機能も実装されている。

それに加えて、なにかと使いがちなcontextまわりの取得がスッキリするという利点があるのでこれからは @nuxtjs/composition-api を使っていこうと思います。