Nuxt.js 入門 #1 – Nuxt.js によるブログアプリ制作

Nuxt.js を利用したアプリケーション開発の手法を紹介していきます。
第一回目はNuxt.jsと WebAPI を用いて簡単なブログアプリを制作してみましょう。

Nuxt.js は Vue.js による Webアプリケーションフレームワークです。

Vue.js や、VueRouter / Vuex と言った周辺ライブラリの機能をフルに活用しながら、
SPA 形式の Webアプリケーションや Node のアプリケーションを構築する事が可能です。

今回は Nuxt.js を使って APIを利用した簡単なブログアプリを作成してみましょう。


はじめに

Nuxt.js は Node を利用した Vue.js のフレームワークです。

Nuxt.js の利用には Node 環境のセットアップと、vue-cli の導入が必要です。

Node 環境の構築セットアップ

Node.js をインストールするには以下のダウンロードリンクより 最新版の Node.js を選択してダウンロードを行ってください。

https://nodejs.org/ja/download/

vue-cli の導入

vue-cli は Vue.js の環境構築を簡単に行うための Node製のツールです。
手元の環境にまだ vue-cli をインストールしていない方は、以下のコマンドで vue-cli をインストールしてください。

$ npm i -g vue-cli

vue-cli のインストールが正常に行えると vue --version のコマンド実行でインストールされているコマンドのバージョンが表示されます。

$ vue --version
2.7.0

Nuxt.js によるアプリケーション開発

vue コマンドのインストールが完了したら、以下のコマンドを実行してプロジェクトのセットアップを行ってください。

$ vue init nuxt-community/starter-template my-vue-app
$ cd my-vue-app
$ npm i

コマンドを実行するといくつか質問が表示されます。
Enter キーを押して回答をスキップするか、任意の値を入力するとプロジェクトテンプレートのダウンロードが始まり次のようなファイル構成が出来上がります。

.
├── assets
├── components
├── layouts
├── middleware
├── node_modules
├── pages
├── plugins
├── static
├── store
├── README.md
├── nuxt.config.js
├── package-lock.json
└── package.json

ファイルが用意されていることを確認したら以下のコマンドでサーバを立ち上げましょう。

$ npm run dev

ブラウザで http://localhost:3000 が開き、 Nuxt.js の初期画面が確認できます。

ページを作成する

Nuxt.js の初期画面は pages/index.vue のファイルで作成されています。

今回はブログのアプリケーションを作成するため記事の一覧を表示する想定で page/index.vue を以下のように書き換えてみましょう。

<template>
  <div>
    <h1 class="title">My Blog App</h1>

    <ul>
        <li v-for="post in posts">{{post.title}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data(){
    return {
      posts: [
        {
          "id": 1,
          "title": "最初の記事です。"
        },
        {
          "id": 2,
          "title": "2番目の投稿です。",
        },
        {
          "id": 3,
          "title": "3番めの投稿です。",
        },
      ]      
    }
  }  
}
</script>

作成したページは http://localhost:3000/ で確認できます。

Nuxt.js でも通常のVue アプリケーションと同じように .vue コンポーネントを作成しながら開発を進めていきます。

中でも pages ディレクトリは URL と紐づく画面を作成するための vue コンポーネントが配置されます。

次に page/about.vue を作成してみましょう。

<template>
  <div>
    <h1 class="title">About this App</h1>

    <p>アプリケーションの紹介文がここに入ります。</p>

    <a href="/">トップページへ戻る</a>    
  </div>
</template>

<script>
export default {
  data(){
    return { }
  }  
}
</script>

この vue コンポーネントは http://localhost:3000/about で確認することが出来ます。
page/about.vuepage/about/index.vue にファイル名を変更しても、同じように /about で確認することが出来ます。
page フォルダ内でのファイル名フォルダ名がそのまま URL として利用される、という構成になっているわけです。

画面遷移

ページ遷移には a ではなく router-link コンポーネントを利用しましょう。

<template>
  <div>
    <h1 class="title">About this App</h1>

    <p>アプリケーションの紹介文がここに入ります。</p>

    <router-link to="/">トップページへ戻る</router-link>    
  </div>
</template>

router-link コンポーネントを利用することで、SPAアプリケーションのシームレスな画面遷移を実装する事ができます。

プログラム上での画面遷移には $router.push を利用するため、以下のように記述することも出来ます。

<template>
  <div>
    <h1 class="title">About this App</h1>

    <p>アプリケーションの紹介文がここに入ります。</p>

    <a @click="$router.push('/')">トップページへ戻る</a>    
  </div>
</template>

動的な URL を処理する

複数のURL形式に対して同じページコンポーネントを表示させたい場合、動的なURLを設定することができます。

例えばブログの投稿詳細画面 を /post/1 post/2 post/3 というURLにする場合、
pages/post/_id.vue というページコンポーネントを作成してみましょう。

<template>
  <div>
    <h1 class="title">POST TITLE</h1>
    <p> ここに記事の本文が入ります。 </p>
  </div>
</template>

<script >
export default {
}
</script>

pages フォルダ内で 先頭に _ 付与したファイル名、フォルダ名の コンポーネントは、
セグメント内のあらゆる表現に対してマッチするようになります。

実際にアクセスされたURL内で使用されているURL上のパラメータは、
{{$router.params.id}}のようにして、$router オブジェクトから取得することが出来ます。


API アクセスとデータのハンドリング

画面の制作が出来たところで、次は Vuex ストアを作成していきましょう。

通常Component 内で利用するデータは data セクションなどで定義されますが、
ページ遷移を伴う大規模なアプリケーションに置いては、 コンポーネント間でのデータ共有のために Vuex が用いられるケースがあります。

Vuex は state / mutation / action の 3つのレイヤに別れた、 Vue.js でのデータ管理機構です。
Vuex Storeは store/index.js を作成して記述します。

export const state = () => ({
  posts: []
})

export const mutations = {
  set (state, items) {
    state.posts = items
  },
}

export const actions = {
  load(ctx){
    const items = [
      {
        "id": 1,
        "title": "最初の記事です。"
      },
      {
        "id": 2,
        "title": "2番目の投稿です。",
      },
      {
        "id": 3,
        "title": "3番めの投稿です。",
      }      
    ]
    ctx.commit("set",items)
  }

}

ストア内でのそれぞれの記述の役割は以下のようになっています。

  • state コンポーネントで使用するデータ
  • mutations stateを変化させるための同期関数
  • actions 実際に非同期処理などを用いてデータを変更する関数

今回は state に 投稿一覧の posts を定義し、また、actions 内に 投稿一覧を設定する load を作成しました。
load 内部では、ctx.commit("set",items) mutations の set を呼び出して値の変更を実施しています。

Vuex ストアの利用

Vuex を利用すると コンポーネント内で利用する様々なデータの処理が、 Vuex ファイル内に分離できます。

例えば page/index.vue は以下のような構成になるでしょう。

<template>
  <div>
    <h1 class="title">My Blog App</h1>

    <ul>
        <li v-for="post in posts">{{post.title}}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data(){
    return {}
  },
  computed:{
    posts(){
      return this.$store.state.posts      
    }
  },
  mounted(){
    this.$store.dispatch("load")
  }
}
</script>

各コンポーネント内では Vuex ストアが自動的にロードされているため、this.$store.state のように記述してこれを参照する事ができます。
上のコードでは data で定義していた 投稿一覧を computed プロパティを利用して、state から読み込む用変更しています。

また mounted フック内で this.$store.dispatch 関数を呼び出すことで、 load アクションを実行し、
state 内の posts の値を更新しています。

Vuex ストアはコンポーネント間で共有の値を管理するためのデータストアの仕組みです。
router-linkを使用した画面遷移では、state の値は引き継がれ次のページにも反映されます。

page/index.vue のテンプレートを次のように書き換え、page/post/_id.vue へのリンクを貼ってみましょう。

<template>
  <div>
    <h1 class="title">My Blog App</h1>

    <ul>
        <li v-for="post in posts">
            <router-link :to="`/post/${post.id}`">{{post.title}}</router-link>            
        </li>
    </ul>
  </div>
</template>

page/post/_id.vue では以下のようにして、URL内のパラメータから該当する記事の情報を取得することが出来ます。

<template>
  <div>
    <article v-if="post">
        <h1 class="title">{{post.title}}</h1>
        <p> ここに記事の本文が入ります。 </p>    
    </article>
  </div>
</template>

<script >
export default {
  data(){
    return {
      post: null
    }
  },
  mounted(){
    for(let post of this.$store.state.posts){
      if(post.id == this.$route.params.id){
        this.post = post
      }
    }
    if(!this.post){ // 記事が存在しない場合トップへ
      this.$router.push("/")
    }
  }
}
</script>

コレで トップページからのリンクを辿って、それぞれの記事のページに到達することが出来るようになりました。


axios による APIデータの取得処理

最後に実際に API 通信を行って記事のデータを取得してみましょう。

今回は、JSON Placeholder というサイトで公開されている POST API を使用します。

http://jsonplaceholder.typicode.com/posts

axios による API 通信

axios は Node製の API 通信ツールです。

axios を利用するためにまずは、 axios のインストールを行いましょう。

$ npm i axios

axios のインストールが完了したら、store/index.js に次のように記述し、API 通信の処理を追加します。

import axios from "axios"

export const state = () => ({
  posts: []
})

export const mutations = {
  set (state, items) {
    state.posts = items
  },
}

export const actions = {
  load(ctx){
    axios.get("http://jsonplaceholder.typicode.com/posts").then((result)=>{
      ctx.commit("set",result.data)
    })
  }
}

これで アクション load を呼び出した際にAPI 通信が実行され、結果が state に保存されるようになります。

Vuexストア の中身は Vue.js の Chrome拡張機能 でも確認する事ができるので是非試してみてください。


Nuxt.js の活用

以上の流れで API を利用したSPA制作のフローを 簡単に確認する事が出来ました。

今回紹介した基本機能を使用して Nuxt.js で様々なアプリケーション開発を行うことが出来るようになっていますが、
Vue.js の各種機能や Nuxt.js のより応用的な使い方を理解することで、複雑なアプリケーション開発もより効率的に進められるでしょう。

基本的なファイル構造や制作の流れがつかめればその他の記法等の理解はスムーズになるため、
今回のブログアプリケーション開発をしっかり理解した上で、その他のドキュメントを確認すると、
より深い Nuxt.js に関する理解が得られるでしょう。

Nuxt.js 入門 その他の記事はこちら

https://www.chatbox.blog/category/nuxt-js/

Nuxt.js 公式ガイドはこちら

https://ja.nuxtjs.org/guide

Nuxt.js 入門 #1 – Nuxt.js によるブログアプリ制作」への1件のフィードバック

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です