Nuxt.js のスニペット集

このページは、Nuxt.js のスニペットをまとめる予定のページです。

目次

注意

  • コードのライセンスは CC0 (クレジット表示不要、改変可、商用可) です。
  • 言語は基本的に TypeScript です。

スニペット

head (vue-meta)

<html> lang 属性の追加

nuxt.config.js
  head: {
    htmlAttrs: {
      lang: 'ja'
    },
    // 略
  },

レイアウト

レイアウトの切り替え

layouts/blank.vue
<template>
  <nuxt />
</template>
pages/index.vue など
<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  layout: 'blank', // レイアウト名を指定
})
</script>

ページ

ページ遷移アニメーション

assets/common.scss など
/** トランジション */
.page-enter-active, .page-leave-active {
  transition: opacity .2s;
}
.page-enter, .page-leave-to {
  opacity: 0;
}
nuxt.config.js
css: [
  '~/assets/common.scss'
],

Axis Module

トランスパイル

nuxt.config.js
  build: {
    transpile: [
      '@nuxtjs/axios'
    ],
  }
  • IE11 や旧 Edge などで動作させたいときに使用します。

baseURL の設定 (処理上)

pages/index.vue など
this.$axios.setBaseURL('https://example.com')

baseURL の設定 (dotenv)

nuxt.config.js (冒頭)
require('dotenv').config()
.env (API_URL に URL を指定)
API_URL=http://localhost:1234

baseURL の切り替え (dotenv 開発・本番)

開発時 (nuxt) は .env.development, 本番時 (nuxt build) は .env.production ファイルを使用する設定です。

nuxt.config.js (冒頭)
require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` })
nuxt.config.js
  modules: [
    // 略
    ['@nuxtjs/dotenv', { filename: `.env.${process.env.NODE_ENV}` }],
    // 略
  ],
.env.development
API_URL=http://localhost:1234
.env.production
API_URL=https://example.com

baseURL の切り替え (dotenv 開発・本番 + proxy)

開発時 (nuxt) は .env.development, 本番時 (nuxt build) は .env.production ファイルを使用する設定です。
@nuxtjs/proxy を使用して、CORS のエラーを回避します。

インストール
npm i @nuxtjs/proxy -D
nuxt.config.js (冒頭)
require('dotenv').config({ path: `.env.${process.env.NODE_ENV}` })
nuxt.config.js
  modules: [
    // 略
    ['@nuxtjs/dotenv', { filename: `.env.${process.env.NODE_ENV}` }],
    '@nuxtjs/proxy',
    // 略
  ],
  proxy: {
    '/api': {
      target: process.env.API_PROXY_URL,
      pathRewrite: {
        '^/api' : '/'
      }
    }
  },
.env.development
API_URL=http://localhost:3000
API_PROXY_URL=http://localhost/api
.env.production
API_URL=https://example.com
API_PROXY_URL=https://api.example.com
pages/index.vue など
const data = this.$axios.$get('/api/data') // API_PROXY_URL/data にアクセスした状態になる

Auth Module

インストール
npm install @nuxtjs/auth

ローカル認証

nuxt.config.js
  // 略
  modules: [
    // 略
    '@nuxtjs/auth',
    // 略
  ],
  router: {
    middleware: ['auth'] // すべてのページをデフォルトで認証必要にする
  },
  auth: {
    redirect: {
      login: '/login', // ログインページのURL
      logout: '/login', // ログアウト後のリダイレクトURL
      home: '/', // ログイン後のリダイレクトURL
    },
    strategies: {
      local: {
        endpoints: {
          login: { url: '/api/login', method: 'post', propertyName: 'token' }, /// API のログイン用エンドポイント
          logout: false, // API のログアウト用エンドポイント
          user: false, // API のユーザー情報取得用エンドポイント
        },
      }
    }
  },
pages/login.vue
<template>
  <v-card max-width="350" class="login-card mx-auto">
    <v-card-title>ログイン</v-card-title>
    <v-card-text>
      <v-alert text v-show="error">
        ユーザー名かパスワードが異なります
      </v-alert>
      <v-form>
        <v-text-field
          label="ユーザー名" placeholder="ユーザー名"
          prepend-inner-icon="mdi-account-circle"
          outlined
          v-model="login.username"
        ></v-text-field>

        <v-text-field
          type="password"
          label="パスワード" placeholder="パスワード"
          prepend-inner-icon="mdi-lock"
          outlined
          v-model="login.password"
        ></v-text-field>

        <v-btn block x-large @click="login">ログイン</v-btn>
      </v-form>
    </v-card-text>
  </v-card>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  //layout: 'login', // レイアウト変更
  data () {
    return {
      login: {
        username: '',
        password: '',
      },
      error: false
    }
  },
  methods: {
    async login() {
      this.error = false;
      try {
        await this.$auth.loginWith('local', { data: this.login }); // ログイン
      } catch(error) {
        this.error = true;
      }
    }
  }
})
</script>
pages/index.vue など
<template>
  <div>
    <v-btn @click="logout">ログアウト</v-btn>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'

export default Vue.extend({
  methods: {
    logout () {
      this.$auth.logout() // ログアウト
    }
  }
})
</script>

asyncData() + Axios Module

pages/index.vue など
<script lang="ts">
import Vue from 'vue'
import '@nuxtjs/axios'
export default Vue.extend({
  data () {
    return {
      items: [] as string[]
    }
  },
  async asyncData({ $axios }) {
    const items = await $axios.$get('/items.json')
    return {
      items
    }
  },
})
</script>
static/items.json
["aaa", "bbbb", "ccc"]
  • 補足
    • import '@nuxtjs/axios'$axios の型定義を読み込みます。
    • asyncData() 上では methods 内のメソッドを実行できません (インスタンスが生成されていない)
  • 参考

fetch()

fetch() + Axios Module

※ Nuxt 2.12 以降の fetch() です。
pages/index.vue など
<template>
  <div>
    {{items}}
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import '@nuxtjs/axios'
export default Vue.extend({
  data() {
    return {
      items: [] as string[]
    }
  },
  async fetch() {
    this.items = await this.$axios.$get('/items.json');
  }
})
</script>
static/items.json
["aaa", "bbbb", "ccc"]

fetch(context) + Vuex + Axios Module

※ Nuxt 2.12 以降 fetch(context) は非推奨になっていますが、fetchmiddleware に変更して使用できます。
pages/index.vue など
<template>
  <div>
    {{$store.state.items}}
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
export default Vue.extend({
  async fetch({ store }) {
    await store.dispatch('request');
  }
})
</script>
store/index.ts
import { GetterTree, ActionTree, MutationTree } from 'vuex'
import '@nuxtjs/axios'

export const state = () => ({
  items: [] as string[],
})

export type RootState = ReturnType<typeof state>

export const mutations: MutationTree<RootState> = {
  SET_ITEMS: (state, items) => (state.items = items),
}

export const actions: ActionTree<RootState, RootState> = {
  async request({ commit }) {
    const items = await this.$axios.$get('/items.json')
    commit('SET_ITEMS', items)
  },
}
static/items.json
["aaa", "bbbb", "ccc"]