43
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Nuxt.jsのpluginsにaxiosの共通部品を実装する

Last updated at Posted at 2020-03-01

はじめに

Nuxt.jsにてクライアントサイドのvueからサーバのREST APIを呼び出す際に、vue内のスクリプトにロジックを書くと、他の場所で流用できない。そのため、外部のjsに共通ロジックとしてサーバのAPIを呼び出す処理を記述したかったが、あまり良い例が無かったので、検討&実装してみた(正しいかは不明)
Vuexストア内でaxiosを使ってサーバAPIを呼び出すみたなことをやってる人も居たけど、それはちょっと違うだろう(というか気持ち悪い)ということで、pluginsに共通ロジックを作成することにした。

構成

修正する対象は以下の3ファイル(pages/index.vue , plugins/axios.js , plugins/api.js)

ROOT
 ├─.nuxt
 ├─assets
 ├─components
 ├─layouts
 ├─middleware
 ├─pages
 │      index.vue
 ├─plugins
 │      api.js
 │      axios.js
 ├─server
 ├─static
 ├─store
 └─test

axios.js

以下の記事を参考に、pluginsフォルダ配下にaxios.jsを作成する。
今回は記事のまま修正はしていない。このプラグインを作成することで、axiosでサーバアクセスする際、
リクエスト発生時、エラー発生時に処理をフックして任意の処理を実行することができる。
$axios.onResponseでレスポンス時にフックすることも可能。

axios.js
export default function ({ $axios, redirect }) {
  $axios.onRequest((config) => {
    console.log('Making request to ' + config.url)
  })

  $axios.onError((error) => {
    const code = parseInt(error.response && error.response.status)
    if (code === 400) {
      redirect('/400')
    }
  })
}

api.js

このjsがapiを呼び出す共通部品。

api.js
export default function ({ $axios }, inject) {
  const api = new API($axios)

  inject('api', api)
}

class API {
  constructor (axios) {
    this.axios = axios
  }

  async getHoge () {
    const res = await this.axios.$get('http://localhost:3000')
    console.log(res)
  }
}

次の処理を入れることで、後述するvue内で $api としてアクセスすることができるようになる。

  inject('api', api)

ここまで作成したら、 nuxt.config.js 内の plugins に次のように記載する。

nuxt.config.js
  plugins: [
    '~/plugins/axios',
    '~/plugins/api'
  ],

index.vue

index.vueの<script>部分だけを抜粋。
asyncData() 内ではthisが使えないので、context.app.$api.getHoge()
mounted() 内などのthisが使える箇所では、this.$api.getHoge()
とすることで、api.jsに記載したaxiosの共通ロジックを呼び出すことができる。

index.vue
<script>
import Logo from '~/components/Logo.vue'

export default {
  components: {
    Logo
  },
  asyncData (context) {
    context.app.$api.getHoge()
    return {
    }
  },
  mounted () {
    this.$api.getHoge()
  }
}
</script>

まとめ

この記述がNuxt.jsとして正しいかどうかは、少し微妙なところ。
そもそもAPIクラスを作成する必要が無く、inject('メソッド名', function)とすればよい。
しかし、今回作成したかったアプリケーションは、バックエンドが複数あり、
そのバックエンド毎に処理を実行する共通インスタンス(この例では$api)を
作成したかったからこのようにしている。
$backendA.getHoge(), $backendB.getHoge() のような感じ。

参考

  • Axios Module
    https://axios.nuxtjs.org/
    なぜNuxt.jsの本家サイトにこの例が記載されていないのかが謎ってくらい「なるほどね」ってなった。
  • Nuxt.jsでaxiosの共通処理を作成し、API呼び出し処理をラップして使用する
    https://qiita.com/itouuuuuuuuu/items/4132e3b7ddf2cbf02442
    最初この記事を見つけたときは「おぉ!!」ってなった。次の2点を自分なりに改善してみたのが本記事。
    • export let axios;
      plugins/axios/index.js 内で export let axios; としている。
      axiosをexportしたかったからこのようにしたんだと思うけども、
      これだとESLintのimport/no-mutable-exports に引っかかってしまう。
    • import UserApi from '@/plugins/axios/modules/user'
      作成した共通部品をvue内で使用する際にimportしなければならない。
      これは地味にメンドイ。
43
44
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
43
44

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?