こんにちは!

第一開発事業部の森田です。

私は現在、「画像投稿Webアプリケーションを作成する」という新卒課題に取り組んでいます。このアプリケーションでは、フロントエンドはVue.js、バックエンドはAWS SAMを利用して作成しています。

事業部配属以前の新卒研修ではDjangoでアプリケーション開発を行ったため、フレームワークの何たるかは理解していました。しかし、JavaScriptやVue.jsを触るのは初めてであったため、フロントエンド開発に取り組んだ当初は、Vueプロジェクトは作成できても、どのフォルダにどのようなファイルを格納すべきなのか、どのようなコードを書けば良いのか全くわかりませんでした。

そこで、今回はVueプロジェクトの作成方法から自動生成されるファイルをいじって画面遷移を行うまでを、フォルダ構造やそれぞれのフォルダの役割に着目しながら、解説します。

目次

  1. 前提
  2. Vueプロジェクトの作り方
  3. Vueプロジェクトの構造
  4. Vue.jsで画面遷移をしてみよう

前提

私は以下の環境で実験を行なっています。

  • node v20.15.1
  • npm 10.7.0
  • vue cli 5.0.8

この辺りの環境構築については、以下の記事を参考にしました。環境構築がお済みでない方は是非参考にしてみてください!

Vueプロジェクトの作り方

さて、環境構築が出来たら早速Vueプロジェクトを作っていきましょう。環境構築を済ませておけば、1分でプロジェクトを作ることができます。カップラーメンが3つ作れますね。

まず、ターミナルを開きます。

そして、プロジェクトを作成したいフォルダに移動して、npm create vue@latestを実行します。

そうすると、プロジェクトの設定を行うためのメッセージが出力されます。

k-morita@k-morita1 Desktop % npm create vue@latest
> npx
> create-vue
Vue.js - The Progressive JavaScript Framework
✔ Project name: … sample-app
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit Testing? … No / Yes
✔ Add an End-to-End Testing Solution? › No
✔ Add ESLint for code quality? … No / Yes
✔ Add Vue DevTools 7 extension for debugging? (experimental) … No / Yes
Scaffolding project in /Users/k-morita/Desktop/sample-app...
Done. Now run:
cd sample-app
npm install
npm run dev

二択の質問にいくつか答えるだけで、簡単にVueプロジェクトの設定を行うことができます。今回は画面遷移の機能を作りたいだけなので、Add TypeScript?とAdd Vue Router for Single Page Application development?のみをYesにします。(最初に聞かれるProject nameはsample-appに設定しました。)

プロジェクトを作成したら、Webページ上で立ち上げてみましょう。

プロジェクトはnpm run devで立ち上げることができます。これを実行すると…

k-morita@k-morita1 sample-app % npm run dev
> sample-app@0.0.0 dev
> vite
sh: vite: command not found
k-morita@k-morita1 sample-app % npm install
added 70 packages, and audited 71 packages in 22s
10 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities

おっとsh: vite: command not foundエラーが出てきてしまいましたね。このようなエラーが出た場合は、npm installで依存関係にあるパッケージをインストールしておきます。

これでエラーが解消できるはずです。もう一度実行してみると…

k-morita@k-morita1 sample-app % npm run dev
> sample-app@0.0.0 dev
> vite
VITE v5.4.2 ready in 511 ms
➜ Local: http://localhost:5173/
➜ Network: use --host to expose
➜ press h + enter to show help

何か怪しげなリンクが出てきましたね。これを開いて以下のようなページが出てきたら、とりあえずプロジェクトの作成は完了です。

Vueプロジェクトのページ

Vueプロジェクトの構造


Vue.jsで画面遷移を実装しよう!と言っても、まずはVueプロジェクトの構造を知らないとどこを触っていいか分かりません。そのため、まずはVueプロジェクトのどのフォルダにどのようなファイルを作成するべきかということを簡単にご説明します。

まず、Vueプロジェクトの全体像は下記の通りです。

.
├── README.md
├── env.d.ts
├── index.html
├── node_modules
├── package.json
├── public
├── src
│ ├── App.vue
│ ├── assets
│ ├── components
│ ├── main.ts
│ ├── router
│ ├── stores
│ └── views
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts

名前から何となく役割が推測できるものもありますが、正直このフォルダ名だけ見ても、ほとんどの初学者の方はどこにどのようなファイルを作ればいいかよくわからないと思います。(私もそうでした。)

デフォルトのVueプロジェクトでは以下のような手順でファイルが読み込まれ、Webページが表示されます。

ユーザーがアクセスしたときに表示されるのはindex.htmlになります。

index.htmlの中身を見てみましょう。11行目を見てください。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <link rel="icon" href="/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

11行目のscriptタグで、main.ts(TypeScriptの設定をNoにした場合はmain.js)が読み込まれていると思います。
次にmain.tsを見てみましょう。
main.tsはVueプロジェクトのエントリポイントとなるファイルです。

import './assets/main.css'

import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')

このプログラムの9行目を見ると、createAppでimportした./App.vueを初期化しつつ立ち上げています。
また、14行目のapp.mount('#app')では、index.htmlでdiv id="app"としたところに立ち上げたApp.vueを結びつけています。
それでは、次にApp.vueの中身を見ていきましょう。
画面遷移において大切になってくるのは、20行目の部分です。(style部分は見やすさのために省略しました。)

<script setup lang="ts">
import { RouterLink, RouterView } from 'vue-router'
import HelloWorld from './components/HelloWorld.vue'
</script>

<template>
  <header>
    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
      <HelloWorld msg="You did it!" />

      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/about">About</RouterLink>
      </nav>
    </div>
  </header>

  <RouterView />
</template>

RouterView/では、パスが指定されたときにrouter/index.tsに記述されている情報を元に画面のルーティングを行います。
それでは、次にrouter/index.tsを見てみましょう。

import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import('../views/AboutView.vue')
}
]
})

export default router

例えば、7行目から11行目の部分を見てみましょう。

この部分では、/が指定されたときにHomeView.vueに遷移する設定を行なっています。

pathでは、ドメイン以下のパスを設定します。

nameでは、プログラム内で呼び出す際に使用される名前を設定します。

componentでは、参照するVueファイルを設定します。

このように、Vueプロジェクトはindex.htmlから始まり、最後にcomponentsからWebページの本体のVueファイルが呼び出されて内容が表示されるようになっています。

少し複雑に見えますが、画面遷移に関してはindex.html、main.ts、App.vue、router/index.ts、componentsを抑えていれば最低限の機能は作成することができると思います。

Vue.jsで画面遷移をしてみよう


それでは、実際にVueプロジェクト内のファイルに変更を加えながら、画面遷移機能を作ってみましょう。

index.html→変更なし

main.ts→変更なし

App.vueは以下のように書き換えます。画面1から画面2に遷移したいだけなので、めちゃくちゃシンプルにします。

<script setup lang="ts">
import { RouterView } from 'vue-router';

</script>

<template>
  <div>
    <main>
      <RouterView />
    </main>
  </div>
</template>

次にcomponentsフォルダ配下に画面1と画面2のVueファイルを作成します。それぞれwindow1.vueとwindow2.vueとします。
window1.vueではボタンを押したときにwindow2に遷移するようにします。

window1.vue

<template>
    <div>
      <h1>画面1</h1>
      <router-link to="/window2">
        <button>画面2に遷移する</button>
      </router-link>
    </div>
  </template>

  <script>
  export default {
    name: 'window1'
  }
  </script>  

window2.vue

<template>
    <div>
      <h1>画面2</h1>
      <router-link to="/window1">
        <button>画面1に遷移する
        </button>
      </router-link>
    </div>
  </template>

  <script>
  export default {
    name: 'window2'
  }
  </script>

ボタンを押したときに画面を遷移させる関数を作成しても問題ありませんが、router-linkを利用した方が簡単に書くことができるので、上記のような記法で書いています。

それでは、最後にrouter/index.tsでルーティングの設定をしていきましょう。

import { createRouter, createWebHistory } from 'vue-router'
import window1 from '../components/window1.vue'
import window2 from '../components/window2.vue'

const routes = [
{
path: '/window1',
name: 'window1',
component: window1
},
{
path: '/window2',
name: 'window2',
component: window2
}
]

const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes
})

export default router

パスを与えたいVueファイルをimportし忘れないようにしましょう。

また、importの際に、使用しているIDEによっては「モジュール ‘../components/window1.vue’ の宣言ファイルが見つかりませんでした。’sample-app/src/components/window1.vue’ は暗黙的に ‘any’ 型になります。」というエラーが出ることがありますが、プログラムとしては問題なく動作するので、ご安心ください。

さて、画面遷移に必要なコードは全て記述できました。npm run devを実行して、ローカルホストのアドレスから作成したページを表示してみましょう。
あれ?空白のページが出てきてしまいました…

これは当たり前で、router/index.tsでhttp://localhost:5173/のパスにアクセスしたときに表示するページを設定していないからですね。
気を取り直してパスを設定したhttp://localhost:5173/window1にアクセスしてみましょう。

ちゃんと画面1という文字と画面遷移のためのボタンが表示されましたね。
それでは次にこのボタンを押してみましょう。

お!画面遷移できましたね。パスもwindow1からwindow2に変わっていることがわかります。

これでVue.jsで画面遷移が出来ました!
画面遷移するプログラムは書けましたでしょうか?少しでも参考になれば幸いです。