第2回 – サンプル作成したVue.jsのプロジェクト解析

2019.04.16

みなさん、こんにちは。
春らしい陽気になったかと思えば、いきなり寒くなり、気温のアップダウンが激しい今日この頃です。
体調崩していませんか?
妻と娘が風邪をひきまして、「なんでパパだけ風邪ひいてないの⁉︎・・・あ、バカだからか!」と妻に
おちょくられた むつたく です。
・・・丈夫なんじゃい!!!

 

 

さて、Vue.jsについて第2回目(前回はこちら)になりますが、サンプルのプロジェクトを作成したかと思います。
今回はそのプロジェクトを掘り下げていこうと思ってます。
ターゲットはVue.js初心者、入門者になりますので、あしからず。

 

やること

  • ディレクトリ構成と各ファイル説明
  • ファイル解析
  • ページ追加

 

 

ディレクトリ構成

vue create <ProjectName>を実行するとプロジェクトディレクトリが作成されました。
今回はプラグインを選択する際、デフォルト(babel/eslint)+Vue-Routerを選択した場合で、話を進めていきます。

 

ディレクトリ構成は、以下のような構成になっていると思います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
.git/              # バージョン管理システムGitのディレクトリ
node_modules/      # npm install コマンドでインストールしたnpmパッケージを管理するディレクトリ
public/            # webpackに処理されないアセットを格納するディレクトリ
 ├ favicon.ico     # ファビコン
 └ index.html      # index.htmlテンプレート
src/
 ├ assets/         # webpackに処理されるアセットを格納するディレクトリ
 ├ components/     # UIコンポーネント(単一ファイルコンポーネント)
 ├ views/          # webpackに処理されるアセットを格納するディレクトリ
 ├ App.vue         # 実行エントリポイントとなるコンポーネント
 ├ main.js         # アプリケーションのエントリポイントのスクリプトファイル
 └ router.js       # Vue-Routerのルーティングファイル
.gitignore         # Git の管理に含めないファイルを指定するためのファイル
babel.config.js    # Babelの設定ファイル
package.json       # npmのモジュール、タスク定義
package-lock.json  # 依存パッケージが依存するパッケージのバージョン情報が変わる場合、package.jsonだけではnode_modulesを別環境で再現できなくなる。それを解決するためのファイル。
README.md          # プロジェクトのREADMEドキュメント。npmコマンドの一覧が書かれている

 

ここでは特に覚えておいて欲しいものを列挙します。

dist ディレクトリ

このディレクトリは、以下のコマンドを実行すると作成されます。

1
$ npm run build

ビルドが完了するとこのディレクトリにバンドルファイルが配置されます。
出力されたファイル一式を任意のサーバにデプロイすれば、一般への公開も可能です。

 

public ディレクトリ

webpackによって処理されないアセットを格納します。
何を言っているんだ・・・ということですが、publicディレクトリ内のリソースはwebpackによる処理はされず、distディレクトリにコピー、配置されます。
今回で言えば、publicディレクトリの配下に[favicon.ico]と[index.html]があると思います。
これらはそっくりそのまま、distディレクトリに配置(コピー)される訳です。

 

また、index.htmlファイルはシングルページアプリケーションの起点になるファイルです。
このファイルを元に、バンドリングされるJSファイルのURLがscript要素のsrc属性に自動的に挿入されます。
さらに、このファイルとバンドリングされたJSファイルやアセットがdistディレクトリ(ビルド時に作成される)に配置されます。

 

src ディレクトリ

webpackによって処理されるアセットを格納します。
publicディレクトリと反対、要は開発ディレクトリです。アプリケーションで使用する、jsファイルだったり、cssファイルだったり、vueファイルを配置してきます。

 

srcディレクトリの配下に別のディレクトリもありますね。assetsディレクトリ、compornentsディレクトリとviewsディレクトリ。

assets ディレクトリ

コンポーネント内で使用する画像ファイルやscssファイルを配置します。
srcディレクトリ配下なので、webpackによる処理を加えるファイルはこのディレクトリに格納します。

 

compornents ディレクトリ

.vueファイル(単一ファイルコンポーネント)を格納します。
アプリケーション内で何度も使うようなパーツはコンポーネント化しておくと便利です。

 

views ディレクトリ

ページデータを格納します。拡張子は.vueです。

 

App.vue ファイル

viewsディレクトリに格納したページはApp.vueを通して表示します。
アプリケーション全体で使うナビゲーションはここで設定します。

 

main.js ファイル

Vueの基本設定ファイルです。App.vueをhtmlに紐付けます。
index.htmlに自動的に挿入される話を先ほどしましたが、このファイルのことになります。

 

router.js ファイル

VueリソースのURLやURLに紐づくコンポーネントを設定します。
通常のWebアプリケーションと違い、SPAにページ内リンクを設置する場合はrouter.jsを編集する必要があります。

 

こんなところでしょうか。
基本的にはNode.jsとかと一緒になると思います。
webpackが???な方は、こちらの記事を読んでみてください。むつたくはこれで理解できました。

 

 

ファイル解析

ここでは、public/index.html、src/main.js、src/App.vue、src/compornents/HelloWorld.vueの中身に触れていきます。
読み込み順的には、index.html -> main.js -> App.vue -> HewlloWorld.vueになります。

 

public/index.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>blog-sample</title>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but blog-sample doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

 

14行目に注目してください。
<div id=”app”></div>とありますが、ビルドを実行するとここにページが挿入されます。
また、アプリケーション共通のもの(ヘッダやフッタ等)をここに書くといいと思います。

 

src/main.js

 

1
2
3
4
5
6
7
8
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

 

先にも記載した通り、ここに設定を書き込みます。
Vueのインスタンスを作成して、App.vueを読み込み、index.htmlにマウントする(書き込む)訳です。

 

src/App.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
<template>
  <div id="app">
    <img alt="Vue logo" src="./assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld.vue'

export default {
  name: 'app',
  components: {
    HelloWorld
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

 

ここでは、テンプレート内で更にHelloWorld.vueを読み込み、それを表示しています。深くなってきましたね。
9行目でHellowWorld.vueを読み込み、13〜15行目でコンポーネント化し、4行目でコンポーネント化したHelloWorldを表示しています。
ついでにmsgも渡しちゃってます。

 

src/compornents/HelloWorld.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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

 

ここが、実際にブラウザに表示されている部分になります。
propsでデータの受け取りを行いますので、記載されてるのは36〜38行目ですね。

 

ちなみにpropsは、コンポーネントが扱うことのできる属性のリストを表すオブジェクトです。コロンを挟んで左のキーが属性名、右の値が属性値が一致すべき条件(StringやらBooleanやら)です。

 

ページ追加

ページ追加するにあたって、ページ遷移は必須になります。
ここはひとつ、ルーティング機能を使用してみましょう!

 

追加するページの作成

簡単でいいと思いますので、こんなのでいかがでしょう。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png" />
    <HelloWorld msg="Welcome to Your Vue.js App" />
  </div>
</template>

<script>

import HelloWorld from "@/components/HelloWorld.vue";

export default {
  name: "home",
  components: {
    HelloWorld
  }
};
</script>

 

App.vueに記載されていた内容をごっそり持ってきてます。
名前を「Home.vue」とします。

 

 

1
2
3
4
5
<template>
  <div class="newpage">
    <h1>This is a new page!</h1>
  </div>
</template>

 

This is a new page!とだけ表示するページです。名前を「Newpage.vue」とでもしときましょう。
このvueファイルをsrcディレクトリ配下に「views」というディレクトリを作成し、その中に配置します。(すでにviewsディレクトリがある方はファイルの配置だけです。)
また、Home.vueもこの中に配置しちゃいましょう。

 

これだけではブラウザに表示できませんので、以下で表示できるようにあれこれ設定していきましょう。

 

vue-Routerの導入

vue-Routerを追加していない方は、プロジェクトディレクトリまで移動して、以下のコマンドを実行してください。

1
npm i -D vue-router

これでルーティング導入しました。

 

router.jsの導入

srcディレクトリの配下に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
import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue";
import Newpage from "./views/Newpage.vue";

Vue.use(Router);

export default new Router({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/newpage",
      name: "newpage",
     component: Newpage
    }
  ]
});

 

3、4行目で使用するページを読み込んで、11行目以降でrouterに設定していくようになります。

main.jsの書き換え

vue-Routerを使用しますので、以下のように書き換えます。

1
2
3
4
5
6
7
8
9
10
import Vue from "vue";
import App from "./App.vue";
import router from "./router"; //★ここ追加

Vue.config.productionTip = false;

new Vue({
  router,              //★ここ追加
  render: h => h(App)
}).$mount("#app");

App.vueの書き換え

vue-Routerのリンク機能を使用しますので、こんな感じに変わります。

 

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
<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/newpage">NewPage</router-link>
    </div>
    <router-view />
  </div>
</template>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
#nav {
  padding: 30px;
  a {
    font-weight: bold;
    color: #2c3e50;
    &.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

 

ここまで出来ましたら、 npm run serve してからローカルホスト(http://localhost:8080)を起動してみてください。
ページ上部にリンクが作成されてるはずです。
そのリンクをクリックすると、作成したページに遷移出来てればOKです!

 

如何だったでしょうか?
ディレクトリ構成や、各ファイルの理解は少し深まりましたでしょうか?
深まってくれると嬉しいです笑

 


 

次回が最後かな。
今、音声認識API(SpeechRecognition)を使ってあれこれしていますので、
API呼び出しなんかお伝えしていこうかなと思います。


Top