はじめに
本記事はVue.jsでフロントエンドを開発する方法について記載しています。
Vue.jsは、Webアプリケーションのユーザーインターフェースを構築するためのJavaScript Frameworkです。
リアクティブなデータバインディング、ルーティング、状態管理などの機能を活用してSPAの構築を容易にします。
また、Webpack、Babel、ESLintなどのツールとシームレスに統合可能とし、開発の生産性を向上する仕組みが用意されています。
Vue.jsを使用する理由
なぜVue.jsを使用するかについて、Vue.jsの主な特徴について以下に記載しています。
シンプル
直感的なAPI操作で開発できるため、ReactやAngularなどの他のフレームワークと比較して、文法が読みやすいです。
パフォーマンス
Vue.jsはReactと同様に仮想DOMを採用しています。
従って実際のDOMを直接操作せずに、仮想DOMを介して変更を行うことで、ブラウザのレンダリング処理を最適化しています。
また、レンダリング処理の最適化の仕組みを行うために、リアクティブシステムを活用し、データの変更を自動的に反映します。
コンポーネントベース
コンポーネント機能によってUIを再利用可能なパーツに分割し、保守性に優れたアプリケーションの開発が可能です。
Vue.js開発
Vue.jsの最新のメジャーバージョンは、本記事執筆時点でVue 3です。
Vue 2のサポートについては、2023年12月31日に終了が予定されています。
よくある質問のVue 2 と Vue 3 の違いは何ですか?から大まかな違いについて確認できます。
基本的に後方互換性があるものの、Vue 3 移行ガイドのBreaking Changesを踏まえて、重大な変更がリストされています。
本記事では、Vue.js のバージョンは2で作成し、以下のプラグインを有効にしてます。
- Babel
- Router
- Vuex
- Linter / Formatter
Vue.jsは、Options APIと、Composition APIの2種類の書き方があります。
詳細は公式ドキュメント2 つの API スタイルをご参照ください。
本記事では便宜上、Vue.jsのバージョンは2で作成しています。
後述するVuetifyは、現在Vue 3に対応しているのでこれから新規に開発する場合は、Vue 3で作成することをお勧めします。
チュートリアル
公式のチュートリアルは、環境構築不要ですぐに試すことができます。
また、Microsoftが提供しているトレーニングからVue.js の最初の手順もお勧めです。
Dockerを使用したフロントエンド開発
Dockerを使用してフロントエンド開発を行う例について以下に記載します。
ソースをマウントしている状態になるため、コードの変更は自動的に行われることで、柔軟に開発を行うことができます。
また、本記事では以下のフレームワーク及びライブラリを導入します。
- Vuetify
- vue-good-table
- axios
- Vuelidate
環境構築
ソースを格納しているカレントディレクトリ(.)を起点にした、本記事のサンプルコードは以下の構成です。
.
├── frontend
│ ├── Dockerfile
│ └── app
└── docker-compose.yaml
- docker-compose.yaml
version: '3'
services:
vue-app:
build:
context: "./frontend"
dockerfile: "Dockerfile"
ports:
- 8080:8080
volumes:
- ./frontend/app:/src
tty: true
environment:
- NODE_ENV=development
- Dockerfile
FROM node:18.12.0-buster
ENV TZ Asia/Tokyo
WORKDIR /src
RUN yarn global add @vue/cli
FROMで指定しているnode:18.12.0-buster
は、Debian 10を基にしたイメージです。
またdockerhubに格納されているnodeのイメージはOfficial Imagesのnodeから確認できます。名前にslim
が付いているイメージは軽量です。
上記コードを配備後、以下のコマンドを実行してデプロイします。
$ docker-compose up -d
出力例
Docker Compose is now in the Docker CLI, try `docker compose up`
Building vue-app
[+] Building 86.1s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 130B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:18.12.0-buster 3.4s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [1/3] FROM docker.io/library/node:18.12.0-buster@sha256:e1432b8cf918f690816d66fcc4f2f687a8d19f7327006b93f17c2f5562c27761 27.6s
=> => resolve docker.io/library/node:18.12.0-buster@sha256:e1432b8cf918f690816d66fcc4f2f687a8d19f7327006b93f17c2f5562c27761 0.0s
=> => sha256:79b2348c51724c2fbd4265526abf4a048e91f8e2fb77909b067526281003b973 2.21kB / 2.21kB 0.0s
=> => sha256:fd31ec14dccdcda8f2472547f1a94ef0a23b8dabb764cd7b1d48aeee0afea7c8 50.45MB / 50.45MB 3.6s
=> => sha256:1b6422bfa32650e77d346bbb40c6b2a0dc34c863e10cfb1a117e8da9796694cd 7.86MB / 7.86MB 1.6s
=> => sha256:e1432b8cf918f690816d66fcc4f2f687a8d19f7327006b93f17c2f5562c27761 776B / 776B 0.0s
=> => sha256:9087e687d2a0976cfaef646af129bb582cc1957e1f0e2f2361adc4759a62fdb8 7.52kB / 7.52kB 0.0s
=> => sha256:335cbfc794fe106b207828e6c9d76fb72aa4631aad91b744e23442082275b8af 10.00MB / 10.00MB 1.8s
=> => sha256:2a348ba61fbef6dec66be0354c013afc02f0bba15b891b9625ac45bb007e9726 51.84MB / 51.84MB 4.4s
=> => sha256:f1ac0452e7a7ce5a9781502e1bca3360740aa17c776748eb301c26ca8f5b294a 192.51MB / 192.51MB 11.5s
=> => sha256:7a53749a183a965085e17a671ec23dd3531d7db1f33675510464db37004814f3 4.20kB / 4.20kB 3.9s
=> => sha256:b434b0ee04a518edc0829d6dec9b1f49ddbeea75c527f7cb576d3ce4f1567710 44.65MB / 44.65MB 6.1s
=> => sha256:4042bd817530b7e52881ffc74407bcb3630517449726461eb318366bf862f4cb 2.28MB / 2.28MB 5.1s
=> => extracting sha256:fd31ec14dccdcda8f2472547f1a94ef0a23b8dabb764cd7b1d48aeee0afea7c8 4.1s
=> => sha256:6d5d9edc827c36a0c3a368899a3c088b98ff482ecd8d102c10922513c2aab42e 454B / 454B 5.5s
=> => extracting sha256:1b6422bfa32650e77d346bbb40c6b2a0dc34c863e10cfb1a117e8da9796694cd 0.5s
=> => extracting sha256:335cbfc794fe106b207828e6c9d76fb72aa4631aad91b744e23442082275b8af 0.6s
=> => extracting sha256:2a348ba61fbef6dec66be0354c013afc02f0bba15b891b9625ac45bb007e9726 3.3s
=> => extracting sha256:f1ac0452e7a7ce5a9781502e1bca3360740aa17c776748eb301c26ca8f5b294a 8.2s
=> => extracting sha256:7a53749a183a965085e17a671ec23dd3531d7db1f33675510464db37004814f3 0.1s
=> => extracting sha256:b434b0ee04a518edc0829d6dec9b1f49ddbeea75c527f7cb576d3ce4f1567710 2.5s
=> => extracting sha256:4042bd817530b7e52881ffc74407bcb3630517449726461eb318366bf862f4cb 0.2s
=> => extracting sha256:6d5d9edc827c36a0c3a368899a3c088b98ff482ecd8d102c10922513c2aab42e 0.0s
=> [2/3] WORKDIR /src 0.2s
=> [3/3] RUN yarn global add @vue/cli 45.1s
=> exporting to image 9.4s
=> => exporting layers 9.4s
=> => writing image sha256:f52afd282f8fbca30519461e62c0208f51f34613009a091084ab487dd05d8fcb 0.0s
=> => naming to docker.io/library/desktop_vue-app 0.0s
WARNING: Image for service vue-app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating desktop_vue-app_1 ... done
コンテナのビルド時に、Vue CLI(※現在はメンテナンスモード)をインストールしています。
Vue CLIは、Vue.jsのプロジェクトを作成し、開発環境をセットアップするためのツールです。
Vue.jsのプロジェクトを生成するためのテンプレート提供や、CLI プラグインを用いて効率的な開発を実現します。
プロジェクトの作成
Vue.jsなどのフレームワークでは、プロジェクトを作成することで、Webアプリケーションを構築するために必要なファイルやライブラリのセットを含むプロジェクトを作成します。
プロジェクトを作成するためには、コンテナにログイン後、以下のコマンドを実行します。
$ vue create .
プロジェクト作成時の出力例について以下に記載します。
出力例
Vue CLI v5.0.8
? Generate project in current directory? Yes
? Please pick a preset:
Default ([Vue 3] babel, eslint)
Default ([Vue 2] babel, eslint)
❯ Manually select features
? Check the features needed for your project: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
❯◉ Babel
◯ TypeScript
◯ Progressive Web App (PWA) Support
◉ Router
◉ Vuex
◯ CSS Pre-processors
◉ Linter / Formatter
◯ Unit Testing
◯ E2E Testing
? Choose a version of Vue.js that you want to start the project with
3.x
❯ 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a linter / formatter config:
ESLint with error prevention only
ESLint + Airbnb config
❯ ESLint + Standard config
ESLint + Prettier
? Pick additional lint features: (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
❯◉ Lint on save
◯ Lint and fix on commit
? Where do you prefer placing config for Babel, ESLint, etc.? (Use arrow keys)
❯ In dedicated config files
In package.json
? Save this as a preset for future projects? (y/N) N
? Pick the package manager to use when installing dependencies: (Use arrow keys)
❯ Use Yarn
Use NPM
プロジェクト作成時の各質問の説明は以下の通りです。
-
Generate project in current directory? Yes:
- 現在のディレクトリにプロジェクトを生成するかどうかの質問で、
Yes
を選択
- 現在のディレクトリにプロジェクトを生成するかどうかの質問で、
-
Please pick a preset:
- プリセットを選択するかどうかの質問で、
Manually select features
を選択
- プリセットを選択するかどうかの質問で、
-
Check the features needed for your project:
- プロジェクトに必要な機能を選択する質問で、
Babel、Router、Vuex、Linter / Formatter
を選択
- プロジェクトに必要な機能を選択する質問で、
-
Choose a version of Vue.js that you want to start the project with:
- Vue.js のバージョンを選択する質問で、
2.x
を選択
- Vue.js のバージョンを選択する質問で、
-
Use history mode for router? Yes:
- routerでhistory モードを使用するかどうかの質問で、
Yes
を選択
- routerでhistory モードを使用するかどうかの質問で、
-
Pick a linter / formatter config:
- Linter / Formatterの設定を選択する質問で、
ESLint + Standard config
を選択
- Linter / Formatterの設定を選択する質問で、
-
Pick additional lint features:
- 追加の Lint 機能を選択する質問で、
Lint on save
を選択
- 追加の Lint 機能を選択する質問で、
-
Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files:
- Babel、ESLint などの設定ファイルをどこに置くかを尋ねる質問で、
In dedicated config files
を選択
- Babel、ESLint などの設定ファイルをどこに置くかを尋ねる質問で、
-
Save this as a preset for future projects? N:
- 今回の設定を将来のプロジェクトで使用するためのプリセットとして保存するかどうかを尋ねる質問で、
N
を選択
- 今回の設定を将来のプロジェクトで使用するためのプリセットとして保存するかどうかを尋ねる質問で、
-
Pick the package manager to use when installing dependencies:
- 使用するパッケージマネージャーを選択する質問で、
Yarn
を選択
- 使用するパッケージマネージャーを選択する質問で、
全ての質問に回答後、インストールが始まります。
? Please pick a preset: Manually select features
? Check the features needed for your project: Babel, Router, Vuex, Linter
? Choose a version of Vue.js that you want to start the project with 2.x
? Use history mode for router? (Requires proper server setup for index fallback in production) Yes
? Pick a linter / formatter config: Standard
? Pick additional lint features: Lint on save
? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files
? Save this as a preset for future projects? No
? Pick the package manager to use when installing dependencies: Yarn
Vue CLI v5.0.8
✨ Creating project in /src.
🗃 Initializing git repository...
⚙️ Installing CLI plugins. This might take a while...
yarn install v1.22.19
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
success Saved lockfile.
Done in 123.79s.
🚀 Invoking generators...
📦 Installing additional dependencies...
yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 54.25s.
⚓ Running completion hooks...
📄 Generating README.md...
🎉 Successfully created project src.
👉 Get started with the following commands:
$ yarn serve
WARN Skipped git commit due to missing username and email in git config, or failed to sign commit.
You will need to perform the initial commit yourself.
以下のコマンドを実行して、ビルドします。
$ yarn serve
yarn run v1.22.19
$ vue-cli-service serve
INFO Starting development server...
DONE Compiled successfully in 14381ms 6:28:22 AM
App running at:
- Local: http://localhost:8080/
- Network: http://172.25.0.3:8080/
Note that the development build is not optimized.
To create a production build, run yarn build.
ブラウザを起動し、http://localhost:8080
にアクセスすると、以下のような画面が表示されます。
アプリケーションの変更は監視されているため、変更があった場合は自動的に再ビルドされます。これにより、開発中のアプリケーションを常に最新の状態で表示できます。
Vuetifyの導入
Vuetifyは、Vue Component Frameworkです。
Vuetifyには、さまざまな種類のUIコンポーネントが含まれています。
Googleをモチーフとしたマテリアルデザインに基づいたデザインシステムを採用しているので、美しく洗練されたUIを作成することができます。
以下のコマンドを実行して、Vuetifyを追加します。
$ vue add vuetify
本記事ではVuetify 2を選択しています。
WARN There are uncommitted changes in the current repository, it's recommended to commit or stash them first.
? Still proceed? Yes
📦 Installing vue-cli-plugin-vuetify...
yarn add v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 4 new dependencies.
info Direct dependencies
└─ vue-cli-plugin-vuetify@2.5.8
info All dependencies
├─ null-loader@4.0.1
├─ rechoir@0.6.2
├─ shelljs@0.8.5
└─ vue-cli-plugin-vuetify@2.5.8
Done in 31.05s.
✔ Successfully installed plugin: vue-cli-plugin-vuetify
? Choose a preset: (Use arrow keys)
Vuetify 2 - Configure Vue CLI (advanced)
❯ Vuetify 2 - Vue CLI (recommended)
Vuetify 2 - Prototype (rapid development)
Vuetify 3 - Vite (preview)
Vuetify 3 - Vue CLI (preview)
インストールが始まります。
? Choose a preset: Vuetify 2 - Vue CLI (recommended)
🚀 Invoking generator for vue-cli-plugin-vuetify...
📦 Installing additional dependencies...
yarn install v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
Done in 31.24s.
⠙ Running completion hooks...
/src/src/views/HomeView.vue
9:9 error Component name "Home" should always be multi-word vue/multi-word-component-names
✖ 1 problem (1 error, 0 warnings)
ブラウザを起動し、http://localhost:8080
にアクセスすると、以下のような画面が表示されます。
公式ドキュメントIcon Fontsのとおりに一般的な4種類のアイコンがサポートされています。
Material Designのアイコンは、Material Design Iconsから検索できます。
vue-good-tableの導入
vue-good-tableは、Vue.jsで使用可能な表(テーブル)をカスタムするためのプラグインです。
様々なデータ形式に対応しています。
テーブルに対して、ソート、フィルタリング、ページネーション、行選択、グループ化、集計などの機能があります。
また、カスタムスロットを使用して、テーブルの見出し、フッター、カラム、セルに独自のコンテンツを挿入することができます。
以下のコマンドを実行してvue-good-tableをインストールします。
オプションに--legacy-peer-deps
を付与することで依存関係を考慮しています。
$ npm install --save --legacy-peer-deps vue-good-table
added 3 packages, removed 1 package, changed 2 packages, and audited 954 packages in 41s
136 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
npm notice
npm notice New major version of npm available! 8.19.2 -> 9.1.1
npm notice Changelog: https://github.com/npm/cli/releases/tag/v9.1.1
npm notice Run npm install -g npm@9.1.1 to update!
npm notice
axiosの導入
axiosは、ブラウザー及びnode.js用のPromiseベースのHTTPクライアントです。
axiosを使用することで、HTTPリクエストの送信や、HTTPレスポンスの受信を行うことができます。
また、PromiseベースのAPIを提供するため、非同期処理を実現することができます。
Vue.jsと組み合わせて使用する場合、Vue.jsのコンポーネント内でデータを取得するために使用されることが一般的です。
以下のコマンドを実行して追加します。
$ yarn add axios
yarn add v1.22.19
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
warning " > @vue/eslint-config-standard@6.1.0" has incorrect peer dependency "eslint-plugin-vue@^7.0.0".
warning "@vue/eslint-config-standard > eslint-import-resolver-webpack@0.13.2" has unmet peer dependency "webpack@>=1.11.0".
warning " > sass-loader@10.3.1" has unmet peer dependency "webpack@^4.36.0 || ^5.0.0".
warning " > vue-cli-plugin-vuetify@2.5.8" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "vue-cli-plugin-vuetify > null-loader@4.0.1" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning " > vuetify-loader@1.9.2" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
warning "vuetify-loader > file-loader@6.2.0" has unmet peer dependency "webpack@^4.0.0 || ^5.0.0".
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 6 new dependencies.
info Direct dependencies
└─ axios@1.1.3
info All dependencies
├─ asynckit@0.4.0
├─ axios@1.1.3
├─ combined-stream@1.0.8
├─ delayed-stream@1.0.0
├─ form-data@4.0.0
└─ proxy-from-env@1.1.0
Done in 13.94s.
Vuelidateの導入
Vuelidateは、Vue.jsアプリケーションでフォームバリデーションを実装するためのライブラリです。
バリデーションルールを定義し、コンポーネントのデータモデルに関連付けることで、入力値のバリデーションを行います。リアクティブな性質を活用し、データが変更されるたびに自動的にバリデーションを行うため、バリデーションの実装が簡単になります。
以下のコマンドを実行して、Vuelidateを追加します。
$ npm install --save --legacy-peer-deps vuelidate
added 1 package, and audited 960 packages in 3s
136 packages are looking for funding
run `npm fund` for details
1 critical severity vulnerability
To address all issues, run:
npm audit fix
Run `npm audit` for details.
おわりに
Vue.jsのコードネームについて「One Piece」や、「Evangelion」など日本のアニメ作品の名前が付けられているのは、創始者及び開発者である尤雨溪氏がアニメ好きなところからきているようです。