見出し画像

小さな渋谷の会社でゼロから作るWebアプリケーション (7) Vue.js導入

株式会社エー・アンド・ディのCTOの山口です。

CTOなのに色々案件が忙しすぎ、かつコロナ禍などのゴタゴタがあり、すっかり更新が滞ってしまいました……。
ようやく落ち着いてきたので、諦めずに更新を再開していきます。

前回でインデックスページの表示まで行えました。
今回は、Vue.jsのシングルファイルコンポーネント(SFC)を使用するところまでやってみようと思います。

Vue.jsとは

Vue.jsとは、詳しくは公式サイトを見てほしいのですが(日本語ドキュメントも充実してます)、簡単にいえばJavaScriptのUI構築用のフレームワークです。

Vue.jsを使うと、Webの画面の構築・管理や、ユーザー入力・データと画面との関連付けが比較的簡単に行えるようになります。

同じような目的でよく採用されるライブラリにReactなどがあります。
それらと比較して、Vueは以下のような特徴があります。

* 単一ファイルコンポーネント(SFC)という仕組みで、画面(HTML・CSS)とそのコード(JavaScript)を一体として管理できる。
* 画面の状態を手軽に扱うことができる。(反面、油断しているとカオスになります……)
* 日本語ドキュメントや日本人ユーザーが多く、導入のハードルが低い。

色々使ってみて、簡単に使えそうに見えて奥が深い(罠も結構ある……)という印象です。
本記事ではなるべく簡単に使う方を強調してやっていこうと思いますが、プロダクションに採用するなど深く関わる場合は、関連プラグインも含めて、公式リファレンスを通読されることをお勧めします。

(というか、プログラミングで何かをちゃんと使う場合は必ず公式リファレンス通読しておくべきですが)

Vue.jsのインストール

さて、早速Vue.jsのインストールを行います。

Vue.jsにはvue-cliという便利ツールがあって、一通りの環境構築を行えたりしますが、今回は使いません。
当初の方針通り、ちゃんと1つ1つ必要なライブラリ・ツールを入れていきます。

まず何はともあれVue.jsをpackage.jsonに追加します。

   // devDependenciesではなくdependenciesに追加
   "dependencies": {
       "vue": "2.6.14",
       "vue-class-component": "7.2.6"
   }

今回はdependenciesへ追加することにしました。

node.jsのパッケージに記載する依存関係のdevDependenciesとdependenciesについて、以下のような違いがあります。

* devDependencies
    * 開発時に必要になる依存パッケージを記載する。
* dependencies
    * 実行時に必要になる依存パッケージを記載する。

これは、node.jsで動かすJavaScript自体についての記載で、今回のような、Webページ等を生成するためにnode.jsを使うパッケージに直接は当てはまらないです……。

(考えようによっては、ビルドという動作を行うパッケージなので全部dependencies)

とはいえ、生成後のWebページで必要になるパッケージと、それらをビルドする時のみ必要になるパッケージとで、明確に2つに分かれるため、以下の基準で分割することにしました。

* devDependencies
    * Webページ・JavaScriptなどをビルドするときのみ必要になるパッケージ
    * webpackやTypeScript、各種プラグインなど
* dependencies
    * 生成後のWebページでブラウザにより使用されるライブラリ
    * Vue.jsなど

というわけで、Vue.jsはdependenciesに記載し、いつも通りinitializeProjectsタスクを実行してインストールします。

単一ファイルコンポーネント(SFC)

Vue.jsの大きな特徴である単一ファイルコンポーネント(SFC)を利用するために、Webpack向けのローダーを追加します。

SFCとは、簡単に言えば下記のような見た目のファイルになります。

<template>
<div class="root">
<!-- なにかしらHTMLを書く -->
{{ message }} <!-- 中括弧の内側はJavaScriptの式 -->
</div>
</template>

<style lang="css">
/* CSSを書く。*/
.root {
   color: red;
}
</style>

<script lang="ts">
// TypeScriptを書く。
import Vue from "vue";
import Component from "vue-class-component";
/**
*  Vueのコンポーネントクラス.
*/
export default class Root extends Vue {
   message = "Hello, MORISOBA!";
}
</style>

こんな感じで、HTML・スタイルシート・スクリプトを1つのファイルにまとめて書くことができます。

vue-loaderのインストール

VueのSFCを使うためのツール・ライブラリはdevDependenciesに追加します。

    // ビルド時に利用するのでdevDependencies
   "devDependencies": {
       // 中略
       "vue-loader": "15.9.7",
       "vue-template-compiler": "2.6.14",
       // 後略
   }

vue-loaderは、webpackでSFCを扱うためのプラグインになります。
vue-template-compilerは、SFCを変換するためのコンパイラ(変換ツール)です。

上記を追記したら、いつもの通りinitializeProjectsを実行してインストールします。

vue-loaderの設定追加

関連ツールのインストールが完了したら、webpack.config.tsに設定を追加します。

// 前略

/**
* ビルドルール定義.
*/
const rules: webpack.RuleSetRule[] = [
   // 中略
   // これを追加
   // Vue SFCルール
   {
       test: /\.vue$/,
       loader: "vue-loader"
   },
];

// 後略

上記を追加できたら、一旦フロントエンドがちゃんと起動できるか確認した方が良いと思います。

C:\Users\ikemen\morisoba\master>.\gradlew.bat :frontend:serve

Vue初期化コードの追加

さて、Vueを実際に使っていくには、Vueの初期化が必要になります。
まだ何もしていないindex.tsに、いよいよ処理を書く事になります。
また、index.htmlについても、Vueのコンポーネントが表示されるよう追記が必要です。

index.htmlには、Vueの管理下に置くルート要素を追加します。

<!DOCTYPE html>
<html>
   <head>
       <meta charset="UTF-8" />
       <title>MORISOBA</title>
   </head>
   <!-- bodyの中身を修正 -->
   <body>
       <div id="app"></div>
   </body>
</html>

今回はSPAとして開発を行うので、画面に表示される要素はすべて上記の<div id="app">タグの中に動的に配置されます。

続いてindex.tsも修正します。

/**
* アプリケーションのエントリーポイント.
*/

import Vue from "vue";

// ルート要素のVueインスタンスを生成する。
new Vue({
   el: "#app",
   render: (h): Vue.VNode => h()
});

Vueをインポートし、index.htmlで追加した要素を指定して初期化を行っています。

まだ何も表示を行わないようになっているので、画面は真っ白になります。
これから要素を描画するSFCを追加していきます。

ルートコンポーネントの追加

SPAでは、基本的には画面の全ての要素をJavaScriptで描画します。
そのための一番根本(ルート)になる要素をまずは追加していきます。

SFC用型定義の追加

まずSFCでもTypeScriptの型チェックが正常に動くよう、以下の型定義をfrontendのsrc/ts/typesディレクトリにvue.d.tsとして追加します。

/**
* Vue SFC向け型定義.
*/
declare module "*.vue" {
   import Vue from "vue";
   export default Vue;
}

Root.vueの追加

次に、frontendのsrc/ts/componentsディレクトリを作成し、以下のRoot.vueファイルを追加します。

<template>
   <div class="root">
       <div class="message">{{ message }}</div>
   </div>
</template>

<style lang="css">
.root .message {
   color: red;
}
</style>

<script lang="ts">
import Vue from "vue";
import Component from "vue-class-component";

/**
* ルートコンポーネント.
*/
@Component
export default class Root extends Vue {
   message = "Hello, MORISOBA!";
}
</script>

以前説明した通り、HTML・CSS・TypeScriptが1つのファイルにまとまっていますね。

Root.vueの描画

Root.vueが追加できたら、index.tsで描画を行うようにします。

/**
* アプリケーションのエントリーポイント.
*/

import Vue from "vue";
import Root from "@/components/Root.vue"; // これを追加

// ルート要素のVueインスタンスを生成する。
new Vue({
   el: "#app",
   render: (h): Vue.VNode => h(Root) // Rootを追加
});

これでフロントエンドを起動すると、ページが以下のように表示されていると思います。
こちらの表示が出ていれば成功です!

画像1

まとめ

Vueを導入してSFCを追加し、コンポーネントを描画できるようになりました。
次回はSCSSの導入について解説を行う予定です!

この記事が気に入ったらサポートをしてみませんか?