こんにちは。
ギークフィードに入社してはや半年が経ちました。
エンジニアのNkawaKです。初めてのブログ投稿になります。
この記事では僕がVue.jsで作ったサンプルを参考にしながら、
シングルページアプリケーション(SPA)とVue.jsについて解説をしていきます。
かなり解説することが多くなってしまったので、前編と後編に分けています。
こちらの前編では、シングルページアプリケーションの構成と画面遷移に焦点を当てて、
解説を行います。
シングルページアプリケーションとは
シングルページアプリケーション(以下SPA)とはその名前の通り、
単一のページでコンテンツの切り替えを行うWebアプリケーションの名称です。
単一のページで構成されているため、ページ遷移の度にロードが発生することなく、
高速で画面が切り替わることがSPAの特徴です。
実際に画面を見ながらSPAの動きを確認してみましょう。こちらのサンプルをご覧ください。
このアプリではWebページはpublic配下のindex.htmlだけですが、
トップページに名前を入力してボタンを押すと、
ロードを挟まずに高速で画面が切り替わっているのが分かります。
このような動きをSPAは、コンポーネントと呼ばれる構成要素を切り替えることで実現しています。
このアプリのソースにある拡張子が.vueになっているものがコンポーネントです。
例えばcomponentsディレクトリにあるTop.vueを見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
<template> <div> <h2>簡単メモ帳</h2> <form @submit.prevent="login"> <label for="name">お名前</label> <div> <input type="text" id="name" v-model="nameForm.name"> </div> <span v-if="error.inValid">お名前を入力してください</span> <div> <button type="submit">利用する</button> </div> </form> </div> </template> <script> export default { data() { return { nameForm: { name: "" }, error: { inValid: false } }; }, methods: { login() { if (this.nameForm.name === "") { this.error.inValid = true; return; } else { this.error.inValid = false; } this.$store.dispatch("login", this.nameForm.name); this.$router.push("/memo"); } } }; </script> |
このファイルは大きく分けてtemplateとscriptという2つの構成になっています。
templateがHTMLのDOM要素を、scriptが関数を使った画面の挙動をそれぞれ定義しています。
トップページではTop.vueのtemplate部分が表示され、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
<template> <div> <h2>簡単メモ帳</h2> <form @submit.prevent="login"> <label for="name">お名前</label> <div> <input type="text" id="name" v-model="nameForm.name"> </div> <span v-if="error.inValid">お名前を入力してください</span> <div> <button type="submit">利用する</button> </div> </form> </div> </template> |
次のメモ帳ページではMemoForm.vueのtemplate部分が表示されています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<template> <div> <h5>ようこそ、{{ name }}さん</h5> <form @submit.prevent="postMemo"> <label for="memo">メモ</label> <div> <textarea id="memo" cols="30" rows="10" v-model="memo.text"></textarea> </div> <span v-if="error.inValid">メモを入力してください</span> <div> <button type="submit">メモる</button> </div> </form> <MemoList :items="this.memoList" @delete="deleteMemo"/> <RouterLink to="/">トップに戻る</RouterLink> </div> </template> |
このようにSPAではwebページ全体を読み込むことなく、webページの一部を構成するコンポーネントのみを切り替えるため、高速にページ遷移を行うことが可能となっています。
Vue.jsを使ってコンポーネントを作成する
コンポーネントはAngular.jsやReact、Vue.jsなどのJavaScriptフレームワークを使って作成します。今回はVue.jsを使ってアプリを作成しているので、Vue.jsによるコンポーネントの作り方を解説していきます。
SPAを構築するために、まずはルートコンポーネントをwebページに適用する必要があります。
main.jsをご覧ください。
1 2 3 4 5 6 7 8 9 10 11 12 |
import Vue from "vue"; import router from "./router"; import store from "./store"; import App from "./App.vue"; new Vue({ el: "#app", router, store, components: { App }, template: "<App/>" }); |
main.jsの1行目でVue.jsを、4行目でルートコンポーネントにあたるApp.vueをインポートしています。
2行目と3行目ではVueRouterとVuexというコアライブラリのモジュールをインポートしています。
これらについては後ほど解説します。
6行目以降からVueインスタンスを生成しています。
1 2 3 4 5 6 7 |
new Vue({ el: "#app", router, store, components: { App }, template: "<App/>" }); |
7行目のel: “#app”は、Vueインスタンスが適用される範囲を示しており、index.htmlのid=”app”で囲まれている範囲でVue.jsの機能を使用することができます。
8行目と9行目はVueRouterとVuexのモジュールをインスタンスに含めています。
そして10行目では、インポートしたApp.vueをコンポーネントとして登録しています。
11行目のtemplateでは登録したApp.vueを<App/>という新しいDOMの要素として、使用することを宣言しています。
実際のHTMLでは以下のようにイメージすると分かりやすいと思います。
1 2 3 |
<div id="app"> <App/> </div> |
main.jsでインポートしたApp.vueが<App/>という要素として、el: “#app”の範囲に差し込まれて、
App.vueのtemplate部分が展開されるという流れになっています。
VueRouterによる画面遷移
それではルートコンポーネントにあたるApp.vueの中身を確認してみましょう。
1 2 3 4 5 |
<template> <main> <router-view></router-view> </main> </template> |
なにやら見慣れない<router-view>という要素がありますね。
これは今回使用したVueRouterというライブラリが提供している機能の一つで、
パスに合わせたコンポーネントが<router-view>の部分に描画されます。
今回の例では、”/”でTop.vueを表示し、”/memo”ではMemoForm.vueが表示されます。
<router-view>に表示するコンポーネントはrouter.jsで設定しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import Vue from "vue"; import VueRouter from "vue-router"; import Top from "./components/Top"; import MemoForm from "./components/MemoForm"; import store from "./store"; Vue.use(VueRouter); const routes = [ { path: "/", component: Top }, { path: "/memo", component: MemoForm, beforeEnter(to, from, next) { if (store.getters["name"] === "") { next("/"); } else { next(); } } } ]; const router = new VueRouter({ mode: "history", routes }); export default router; |
1行目ではVue.jsを、2行目ではVueRouter、3行目と4行目ではパスに設定するTop.vueとMemoForm.vueをインポートしています。
5行目ではVuexのモジュールをインポートしています。
今回の例ではユーザー情報の管理にVuexを使用しています。
SPAの開発において、こちらも重要な部分なので後ほど詳しく解説したいと思います。
7行目のVue.use(VueRouter)は、Vue.js用に作られたライブラリを使用する際に記述する関数です。
9行目から25行目までの部分ではアプリのパスを、配列で定義しています。
{ path: “/”, component: Top }のように、パスとコンポーネントをセットでJSONに含める必要があります。
また、17行目のbeforeEnter(to, from, next)という関数で、パスのページにアクセスする前の処理を行うこともできます。今回ではstore(Vuexのモジュール)で管理しているユーザー情報の名前が空の場合に、トップページへ戻す処理を挟んでいます。
例えば、トップページの名前の欄を入力せずに、/memoのパスにアクセスしようとした際には、強制的にトップページへ戻されます。
27行目から30行目の部分で、routerという定数にVueRouterのインスタンスを代入しています。
VueRouterのインスタンスに先程確認したパスの配列を含めることで、ルーティングとして機能するようになります。
27行目のmode: “history”を書くことで本来のURLの形式で、ルーティングが行われます。
この部分を省くと/#/や/memo#/のように、ハッシュがパスに含まれるようになります。
最後の行でVueRouterのインスタンスが含まれたrouterをエクスポートして、
めでたくこのアプリケーション全体でVueRouterの機能を使用することができるようになりました。
ちなみにVueRouterを使ったリンクは次のように書きます。
1 |
<RouterLink to="/">トップに戻る</RouterLink> |
<RouterLink>というタグで囲って、遷移先のパスをtoで指定すれば、リンクとして機能するようになります。リンクがクリックされたら、パスに指定したコンポーネントに切り替わります。
まとめ
- シングルページアプリケーションは単一のページに、コンポーネントというパーツを組み合わせ作られている
- コンポーネントは<template>というタグの中にhtmlのコードを書いて、拡張子をvueにすれば作れる
- VueRouterというライブラリを使って、パスにコンポーネントを設定すれば、コンポーネントを切り替える、高速な画面遷移を行えるようになる
今回の解説は以上になります。次回はVue.jsの文法とVuexというライブラリについて解説します。
ここまで長らくお読みいただきありがとうございました。
後編もよろしくお願いいたします。
- 【React】フロントエンドのテストコードを書いてみよう【Vitest】 - 2024-04-30
- React Hooks入門ガイド - 2022-03-07
- Vue.jsで構成するシングルページアプリケーション(SPA)の作り方やサンプル例【後編】 - 2020-02-07
- Vue.jsで構成するシングルページアプリケーション(SPA)の作り方やサンプル例【前編】 - 2019-08-05