Nuxt.js テクニック

いろいろ覚えたことメモ。自分用のリファレンスです。
初期設定関連
1.Googleフォントを読み込む
手順1
読み込みたいGoogleフォントのページからCDNのURLを取得例:ニコモジ
この部分をコピペ
手順2
/nuxt.config.jsのlinkの記述がある箇所に以下のように記述
フォントはカンマ区切りで追加できる
手順3
cssで適用させてみる
font-familyの指定はこちらを参照に。
font-familyが適用された!
2.axiosを手動インストールする
axios(アクシオス)とは、非同期通信でデータを取得することのできるjsのライブラリです。
create-nuxt-appでnuxt.jsをインストールするタイミングでもaxiosをインストールしますか?と聞かれるのですが、ここを逃してしまって、後から手動で入れたい場合は以下でインストールできます。公式ドキュメントはこちら
ルートディレクトリでターミナルから下記コマンドを入力(npm使う場合)
npm install --save @nuxtjs/axios

3.作業ディレクトリをsrc配下にまとめる
公式ドキュメントはこちら
完成イメージはこんな感じ。
作業ファイルをsrc配下にまとめて管理しやすくなった
手順1
ルート配下にあるnuxt.config.jsに下記を追記
srcの部分は任意で。(公式ではclientになっているようです)
手順2
ターミナルでsrcディレクトリを作成し、その中にまとめる
$ mkdir src
$ mv assets components layouts pages plugins static store middleware src/

画像パスはそのまま~/assets/img/sample.jpgなどが使えます。
<img src="~/assets/img/sample.jpg" alt="">
4.scssを導入する
手順1
ターミナルから下記3つをインストールする(バージョンは適宜変更してください。)
$ npm install --save-dev sass sass@1.34.1
$ npm install --save-dev sass sass-loader@10
$ npm install @nuxtjs/style-resources@1.1.0
手順2
ルート配下にあるnuxt.config.jsに下記を追記
すると、こんな感じでscssが使えるようになります。
5.pages配下に階層を作る
http://localhost:3000/hoge/foo/みたいに階層化したい場合。
階層化したディレクトリ内に_id.vueファイルを設置する。
/ pages
/area //任意の名前
- _id.vue
- /tokyo //任意の名前
-index.vue
これで自動ルーティングが設定できます。
http://localhost:3000/area/tokyo/でアクセスできるようになります。
6.Google Fontsを使う
わかりやすいようにDotGothic16を適用させてみようと思います。
手順1
Google Fontsのサイトからコードを取得する
引用:Google Fonts
手順2
ルート配下にあるnuxt.config.jsのlink内に下記を追記。
rel: ‘stylesheet’の参照先に、手順1て取得したURLを貼ります。
export default {
head: {
title: 'sample',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [
{ rel: 'stylesheet', href: 'https://use.typekit.net/klr8opc.css' }, //追加
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' }, //追加
{ rel: 'preconnect', href: 'https://fonts.gstatic.com' }, //追加
{ rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=DotGothic16&display=swap' }, //追加
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
],
}
手順3
cssで適用させてみる。
body{
font-family: 'DotGothic16', sans-serif;
}

見た目の実装関連
1.jsonデータから値を取り出す①(ローカルから)
ローカルに設置してあるjsonデータから値を取り出す方法です。
例えばこのようなjsonファイルがローカルにあったとします。
このjsonデータの0番目のnameを取得してみます。
手順1
・pages/hogehoge.vue内のscriptに、インポートしたいjsonファイルのパスを記述する。
・export default内に下記のように定義したものを追記する
<script>
//jsonデータをインポートする(例:users.json)
import userdata from "~/hogehoge/users.json";
//jsonデータを取得する
export default {
data(){
return {
userdata //userdataを定義する
}
}
};
</script>
手順2
template側で定義した値を出力する。
<template>
<p>{{userdata[0].name}}</p>
</template>

2.jsonデータから値を取り出す②(APIから)
JSONPlaceholder(テストとして使えるAPIサービス)を使って、jsonデータから値を取り出すを方法です。
手順1
jsonデータの中身を確認してみる
こんな感じで配列のデータが格納されています
手順2
pages/配下のhogehoge.vueに下記を記述
<script>
const axios = require('axios')
let url = 'https://jsonplaceholder.typicode.com/users' //JSONPlaceholder
//受け取ったjsonデータを画面に表示する
export default {
asyncData({ params }) {
return axios.get(url)
.then((res) => {
return { users: res.data } //usersを定義(res.dataの中にjsonデータが格納)
})
}
}
</script>
手順3
template側で定義した値を出力する。
(手順2で定義したusersを表示する)
<template>
<section>
<h1>
{{users[0].id}},{{ users[0].name}} //キーを指定すると特定のデータを取得できる
</h1>
</section>
</template>
手順4
ブラウザで表示を確認する
jsonデータから値を取り出しできました
ちなみに、以下のようにfor文を使って投稿記事一覧を出すこともできます。
ブログサイトなんかにも使えそうですね。
<template>
<section>
<ul>
<li v-for="post in posts" :key="post.id">
{{post.id}},{{post.title}}</li>
</ul>
</section>
</template>
<script>
const axios = require('axios')
let url = 'https://jsonplaceholder.typicode.com/posts'
//受け取ったjsonデータを画面に表示する
export default {
asyncData({ params }) {
return axios.get(url)
.then((res) => {
return { posts: res.data }
})
}
};
</script>

3.現在のページのクラスのリンクに特定のclass名を付与する
手順1
ルートにあるnuxt.config.jsに下記を追記する。
手順2
html側でリンクを設置する。
この時aタグではなく、nuxt-linkタグを使います。
<template>
<section>
<nuxt-link to="/">トップ</nuxt-link>
<nuxt-link to="/link">link</nuxt-link>
</section>
</template>
ブラウザでnuxt.config.jsで指定したis-activeがついていることが確認できます。
出力結果
4.ヘッダー・フッターをインクルードしたテンプレートファイルを作成する(Nuxt.js v2.13 以下の場合)
pages/xxx.vueで新規ページを作成した時に、ヘッダー・フッター付きのテンプレートファイルから始めるられる状態にする方法です。
手順1
新規ファイルを作成する。
・pagesと同ディレクトリにlayouts/default.vueを作成。
・同ディレクトリにcomponents/header.vueとfooter.vueを作成。
/ pages
/ layouts
- default.vue
/ components
- header.vue ファイル名は任意
- footer.vue ファイル名は任意
手順2
default.vue内に以下コードを記述する。
commonHeader、commonFooterの定義名は適宜変更してOKです。
<template>
<div>
<commonHeader />
<main>
<nuxt />
</main>
<commonFooter />
</div>
</template>
<script>
import commonHeader from "~//components/header.vue"; //headerのインポート
import commonFooter from "~/components/footer.vue"; //footerのインポート
export default {
components: {
commonHeader,
commonFooter
}
};
</script>
手順3
components内に作成したheader.vueとfooter.vueに以下を記述する。
header.vue
<template>
<header>
ここにヘッダー用のhtmlを記述
</header>
</template>
footer.vue
<template>
<footer>
ここにフッター用のhtmlを記述
</footer>
</template>
手順4
動作確認してみる。
pages/配下に適当にファイル作って、ブラウザで表示してみてください。
試しにpages/test.vueを作成して表示してみるとこんな感じ↓

5.コンポーネントファイルを作成して呼び出す
Nuxt.js v2.13 以下では、import宣言が必要でしたが、新しいバージョンでは自動インポートするように設定ができます。
手順1
ルートにあるnuxt.config.jsのexport default 内に下記を追記する。
export default {
components: true, //追記
}
これて自動インポートが適用されます。
手順2
実際にコンポーネントファイルを作成して呼び出してみます。
components/配下にインクルードしたいファイルを作成します(例ではnews.vue)
フォルダ分け階層化にしてもOKです。
/ components
- news.vue
/ fruits
- apple
/ team
- banana
手順3
コンポーネントを呼び出したい箇所には以下のように記述する。
階層化にしている場合は、アッパーキャメルケースでディレクトリ名を指定します。
<template>
<News />
<FruitesApple />
<FruitesTeamBanana />
< /template>
6.nuxt-mq(vue-mq)でレスポンシブ対応する
nuxt-mqは、vue-mqをNuxtで使えるようにSSR対応したものです。
手順1
ターミナルからインストールする
// yarnの場合
$ yarn add vue-mq
// npmの場合
$ npm install nuxt-mq
手順2
ルート配下にあるnuxt.config.jsに下記にのようにを追記する。
modules: [
'@nuxtjs/axios',
[
'nuxt-mq',
{
// Default breakpoint for SSR
defaultBreakpoint: 'sp',
breakpoints: {
sp: 768, //SP時のブレイクポイントを定義
pc: Infinity //PC時のブレイクポイントを定義
}
}
]
],
手順3
html側で使ってみる。
mq-layoutタグで手順2で定義したサイズによって表示が出し分けされます。
タブレットサイズやランドスケープモードなどの細かい出し分けも定義するだけで簡単に設定できます。
<template>
<mq-layout mq="pc">
PCで表示
</mq-layout>
<mq-layout mq="sp">
SPで表示
</mq-layout>
< /template>
7.onclickでクラス名を追加・削除する(v-onとv-bind)
ボタンを押すとclass名の追加、削除を交互にスイッチする動きです。
(jQueryのtoggle的なものです)
手順1
html側には下記のように記述します。
・v-on:clickでクリックで、isShowの値がtrueとfalse切り替わる(クリックで値が反対になる)
・v-bindのclass属性の値は、isShowがtrueの場合is-showが付与される
<template>
<div v-bind:class="{'is-show' : isShow }">クラスが付いたら何か表示する</div>
<div v-on:click="isShow = !isShow">ここをクリック</div>
</template>
script側には、isShowの初期値をfalseにしておくと、最初が非表示、クリックでclass名が追加されます(最初からclass名入れておきたかったらここをtureに)
<script>
export default {
data(){
return{
isShow:false
}
}
}
</script>
8.可視範囲に入ったらクラス名を付与する
スクロールして要素が可視範囲に入ったら表示するやつです。
今回は要素の表示・非表示を検出するプラグインvue-observe-visibilityを使います。
手順1
プラグインをインストールする。
$ npm install --save vue-observe-visibility
手順2
新規ファイルを作成する。
・pagesと同ディレクトリにplugins/observe-visibility.jsを作成。
/ pages
/ plugins
- observe-visibility.js
手順3
手順2で作成したobserve-visibility.js内に下記を追加。
import Vue from "vue";
import VueObserveVisibility from "vue-observe-visibility";
Vue.use(VueObserveVisibility);
手順4
ルート配下にあるnuxt.config.jsに下記にのようにを追記し、このプラグインを適用させる。
export default {
plugins: [
{ src: '~/plugins/observe-visibility.js', mode: 'client' }
],
}
これで設定は完了です。
では、これを実際に使ってみます。
手順5
html側
<div class="box"
v-observe-visibility="visibilityChanged"
v-bind:class='{active:isActive}'>
ここがフェードインする
</div>
css側
<style>
.box{
opacity: 0;
}
.box.active{
opacity: 1;
}
</style>
フェードインアニメとかつけてふわっとしたエフェクトつけたりするとリッチになります。
script側
export default {
data(){
return {
isActive: false, // 初期値はfalse
}
},
methods: {
// visibilityChangedが可視範囲に入るとisVisible01がtrueになる
visibilityChanged(isVisible, entry) {
if(isVisible){
// isVisibleがtrue(=可視範囲に入ったら)になったら処理を実行する
this.isActive = true
}
}
}
}
ちなみに、クラス名がつくのを少し遅延させたい場合はsetTimeoutとかも使えます。
export default {
data(){
return {
isActive: false,
}
},
methods: {
visibilityChanged(isVisible, entry) {
if(isVisible){
setTimeout(() => {
this.isActive = true
},500)
}
}
}
}
9.スライドショーを作る
プラグインvue-awesome-swiperを使ってスライドショーを実装します。
$ npm i --save swiper@5.x vue-awesome-swiper@4.x
その他
1.キャッシュのクリア
// yarnの場合
$ yarn clear-hard-source-cache
// npmの場合
$ npm run clear-hard-source-cache