第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 |
App.vueに記載されていた内容をごっそり持ってきてます。
名前を「Home.vue」とします。
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呼び出しなんかお伝えしていこうかなと思います。
↓↓↓ぜひチェックしてください
~提供中のヒューマンセンシング技術~
◆人物検出技術
歩行者・来店者数計測やロボット搭載も
https://humandetect.pas-ta.io
◆視線検出技術
アイトラッキングや次世代UIに
https://eyetrack.pas-ta.io
◆生体判定技術
eKYC・顔認証のなりすまし対策を!
https://bio-check.pas-ta.io
◆目検出技術
あらゆる目周りデータを高精度に取得
https://pupil.pas-ta.io
◆音声感情認識技術
会話から怒りや喜びの感情を判定
https://feeling.pas-ta.io
◆虹彩認証技術
目の虹彩を利用した生体認証技術
https://iris.pas-ta.io