初学者でもVue/Vuexを[確実に]動かせる記事~はじめてのHelloWorld~

# はじめに
## 導入
ここ数年のwebの主流(?)となりつつあるSPA(Single Page Application)に興味を持っている方は多いのではないでしょうか?[SPA(Single Page Application)の基本](https://qiita.com/takanorip/items/82f0c70ebc81e9246c7a)


この記事の目標は、「この今風のフロントエンドを実際に動かしてみたい!」と思う初学者の方向けに、VUE.jsを採用してSPAを動かすところまで持って行くことです(筆者も普段はバックエンドをメインに開発していますので大丈夫です。)。

SPAの学習で壁は何かというと、単純なHelloWorld、およびその改良ができるようになるのに、数多くのことを学んでいかなければならないことだと私は考えています。それに加えてVUEXやVue-Routerなどを初めから同時に学ぼうとすると挫折しやすいです。
この記事では初学者目線で、**はじめから丁寧に!**を心がけ、**[確実に]**動かせるように書いていきたいと思います。随時他の記事へのリンクもはりますので、随時目を通していただけたら！！



## 一連の連載で[確実に]理解すること一覧

- Vue.jsを使ってHelloWorldを出力し、プロジェクト内のファイルの役割や仕組みを理解する **[本記事]**

- コンポーネントとは何かを理解し、HelloWorldを改良してページのQRコードを表示してみる。**[本記事]**

- コンポーネント間の値の受け渡しの基礎を導入し、Vuexの意義を理解した上で導入する

- WebAPIを導入してフロントエンドとバックエンドでデータをやり取りし、実践的なサイトを作り上げる

# マシンの環境構築
この記事ではVirtualBox/Vagrantを用いた仮想環境をベースに進めていきます。プログラミングについてはやはりLinuxベースの方が進めやすいし、情報量も多いと感じています。WindowsでもVirtualBox/Vagrantは動きますので可能な方はこの際、仮想環境での開発を始めましょう。Virtual Box や Vagrantについての記事は多数あります。

[Vagrant を用いた開発環境での作業
](https://qiita.com/rerere0101/items/c8846453362fb5393c34)

[Windows10にVirtualBoxとUbuntuをインストール
](https://qiita.com/pyon_kiti_jp/items/0be8ac17439abf418e48)

この記事ではOSはUbuntu16.04で進めます。Ubuntu16.04が立ち上がり、コマンドラインが打てる状態になったら次に進みます。


# VUE.js でHelloWorldを実行
## vueの導入
Vueの導入に入ります。まず必須のツールとしてNode.jsとnpm(node package manager)をインストールする必要があります。
<インストール コマンド>

```インストール
sudo apt-get update
sudo apt-get install nodejs
sudo apt-get install npm
```

<バージョンを安定板に>


```バージョンを安定板に
sudo npm cache clean
sudo npm install -g n
sudo n stable
```

[とりあえず Ubuntu で新しい Node.js, npm をインストール
](https://qiita.com/kerupani129/items/60ee8c8becc2fe9f0d28)


node.js はPythonやRubyと同様にサーバサイド(webブラウザから見て"サーバ"サイド)でJavascriptを用いることのできる実行環境です。文法がJavascriptと同じ新しいプログラミング言語という認識で良いです。npm(node package manager)は追加のパッケージ管理をするためのソフトです。Pythonユーザにとってはpipみたいなものとお考えください。


パッケージマネージャーが手に入ったので、Vue.jsをインストールします。
```
npm install -g vue-cli
vue --version
- 2.9.6
```
ここまででvueのバージョンが表示できるようになっているはずです。また**npmの他にyarnも導入しましょう。**

`npm install -g yarn`

yarnもパッケージマネージャーですが、より高速に動作します。他にも違いはあるのですが、今回の記事ではyarnを中心に進めます。

## Hello World
`vue init webpack [フォルダ名]`
でプロジェクトを作成します。いくつか質問されます。Vue-routerについてのみNを押してください.Vue-RouterはSPA環境でのページ遷移を管理するプラグインです。ページ遷移とはつまりアクセスURLについての振り分けや、ページ内のリンクの挿入などを制御している部分です。後から導入ができるので、必要だと感じた際に導入すればいいです。(Ruby on Railsを学んでいた方はRouter制御の経験があるかと思います。)


```
vagrant@vagrant:~/source_code$ vue init webpack hello

? Project name hello
? Project description A Vue.js project
? Author
? Vue build standalone
? Install vue-router? No
? Use ESLint to lint your code? Yes
? Pick an ESLint preset Standard
? Set up unit tests Yes
? Pick a test runner jest
? Setup e2e tests with Nightwatch? Yes
? Should we run `npm install` for you after the project has been created? (recommended) yarn

   vue-cli · Generated "hello".


# Installing project dependencies ...
# ========================

yarn install v1.15.2
info No lockfile found.
[1/5] Validating package.json...
[2/5] Resolving packages...
warning autoprefixer > browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning css-loader > cssnano > autoprefixer > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning css-loader > cssnano > postcss-merge-rules > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning css-loader > cssnano > postcss-merge-rules > caniuse-api > browserslist@1.7.7: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
warning eslint > file-entry-cache > flat-cache > circular-json@0.3.3: CircularJSON is in maintenance only, flatted is its successor.
warning nightwatch > proxy-agent > socks-proxy-agent > socks@1.1.10: If using 2.x branch, please upgrade to at least 2.1.6 to avoid a serious bug with socket data flow and an import issue introduced in 2.1.0
warning webpack-bundle-analyzer > bfj-node4@5.3.1: Switch to the `bfj` package for fixes and new features!
[3/5] Fetching packages...
info fsevents@1.2.7: The platform "linux" is incompatible with this module.
info "fsevents@1.2.7" is an optional dependency and failed compatibility check. Excluding it from installation.
[4/5] Linking dependencies...
[5/5] Building fresh packages...
success Saved lockfile.
Done in 20.92s.


Running eslint --fix to comply with chosen preset rules...
# ========================

yarn run v1.15.2
$ eslint --ext .js,.vue src test/unit test/e2e/specs --fix
Done in 0.94s.

# Project initialization finished!
# ========================

To get started:

  cd hello
  npm run dev

Documentation can be found at https://vuejs-templates.github.io/webpack
```

To get started の通り、
`cd hello`
`yarn run dev`

を実行して見てください。compile successfully!の文字がでたら成功です。webサーバが起動します。
なお、vagrantで環境を構築した場合、IPアドレスを指定して起動することでホストPCのブラウザからアドレスを指定してアクセスできます。
`yarn run dev --hot --host [IPアドレス]`
と打ってみてください。ブラウザで**[IPアドレス]:8080**にアクセスして、以下のような画面が表示されたら成功です。
<img width="1362" alt="スクリーンショット 2019-04-14 11.14.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134021/927c057b-b71c-e486-58a0-55b1a48b490f.png">

## Hello Worldが出力された仕組み
変更を加えて行くためにプロジェクト内のファイルがどうなっているのかを見て行くことにします。
### index.htmlとwebpackについて
はじめにプロジェクトディレクトリのホームに置いてあるindex.htmlについて


```index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <title>hello</title>
  </head>
  <body>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>

```
ここで重要なのは<body>内の二行

```
    <div id="app"></div>
    <!-- built files will be auto injected -->
```
です。Javascriptを用いた動的webページでは、このタグ(ここではタグにid='app'がついている)に対して操作をし、描写します。
*「htmlのコードはたったこれだけなのになんでHelloworldのページはあんな感じになったの?」*　と思った方、このid='app'の部分にjavascriptでweb描写のためのコードを流し込んでいるからです。

また、javascriptやjQueryを使っていた方は
*「Javascriptのコードを読み込む記述がどこにもない」*　と思われたかもしれません。ここで思い出してもらいたいのが**webpack**についてです。
**webpackはCSSやJavascriptファイル、画像ファイル、フォントなど(アセットファイルなんて言い方もします)を一つの実行ファイル、例えばbundle.jsという一つのファイルで吐き出す**ためのプラグインです。このwebpackについての設定は*webpack.config.js*といったファイルに記述することでカスタマイズできます(今回はしなくていいです)。これ以上の説明については、他のわかりやすい記事に譲ることにします。

[フロントエンドエンジニア必見！JavaScript開発現場で人気の「Webpack」とは？
](https://ferret-plus.com/6337)

[webpack.config.jsがわからない
](https://qiita.com/one-kelvin/items/b810aafb6b5ef90789a3)

このwebpacknによって一つにまとめられたファイル(bundle.js)を読み込むための一文がindex.html中にインサートされます。
それが
`<!-- built files will be auto injected -->`
の箇所です。大事なことをまとめると、**ブラウザとして読み込んでいるのはindex.htmlで、そのファイル内部でbundle.jsファイルを読み込んでおり、そのbundle.jsの実態は複数のCSS/JSといったファイルである**ということです。

### package.jsonについて
それぞれのプロジェクト毎に必要な外部プラグインは異なります。「自分が作成しているwebアプリはこのようなプラグインを使っています」というのを表示しているのがpackage.jsonです。npmやyarnで新しいプラグインをinstall(yarnならadd)するたびにpackage.jsonに追記されていきます。


### srcディレクトリの中身(大事)
ホームにあるsrcディレクトリの中身について、プロジェクトの作成の際に**routerをN**にした方は階層は以下のようになっているはずです。

```
vagrant@vagrant:~/source_code/hello/src$ tree .
.
├── App.vue <-- 単一コンポーネント
├── assets
│   └── logo.png
├── components
│   └── HelloWorld.vue  <--単一コンポーネント
└── main.js <--単一コンポーネント達の登録

2 directories, 4 files
```

まず、App.vueやcomponents/HelloWorld.vueについて、これらはVueの世界で**単一コンポーネント**と呼ばれるものです。

[単一コンポーネントについて](https://qiita.com/tkhr/items/ac22019c891fe8fa5f91)

VueやReactなどは**「アプリケーションは部品やパーツの組み合わせでできている」という考え方**に基づいています。そこで、これらのパーツ単位でファイルを分けて記述しておくという発想がでてきます。**.vueファイルはHTML・CSS・JSの文法でパーツ(vueではコンポーネントと呼びます)を作成しているファイル**とお考えください。vueファイルの構成は以下のようになっています。

```
<template>
<!-- 構成を記述。HTMLに相当。　-->
</template>

<script>
<!-- 操作を記述。Javascriptに相当 -->
</script>

<style>
<!-- コンポーネントのスタイリングを記述。CSSに相当 -->
</style>

```


試しにHelloWorld.vueを見ると、構成はtemplate内に書かれていることがわかります。


```HelloWorld.vue
<template>
  <div class="hello">　<!-- scriptから操作される. コンポーネント内ではdivは一つのみ
    <h1>{{ msg }}</h1>  <!-- scriptからデータを受け取り表示している箇所
    <h2>Essential Links</h2>
    <ul>
      <li>~省略~</li>
      <li>~省略~<li/>
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld', // コンポーネントには大文字の単語二つ程度の組み合わせで名前付け 
  data () {
    return {
      msg: 'Welcome to Your Vue.js App' // コンポーネントの保持するデータ
    }
  }
}
</script>
```

例えばdata()内部のmsgを好きな文字列に変更してみてください。ブラウザを再読み込みすることで、msgの部分で表示される文字列が変わったことがわかると思います。コンポーネントはこのようにして記述していきます。コンポーネントの利点の一つに、一度作ってしまったら使い回しが自由自在ということがあります。今回作ったHelloWorld.vueを使い回しているのがApp.vueです。**App.vueはページ全体をさす単一コンポーネントであり、絵を書く場面で言うとキャンバスのようなもの**とお考えください。

[Vue.js いろいろまとめ
](https://qiita.com/SatoTakumi/items/36204b04e5743d666a26)

```App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <HelloWorld/> <!-- ここで読み込んだコンポーネントを配置
  </div>
</template>

<script>
import HelloWorld from './components/HelloWorld' // この部分でコンポーネントファイルを読み込んでいる。

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>
```

これらのコンポーネントの登録および、コンポーネントのnewを扱うのがsrc内のmain.jsです。main.jsのみスコープ的にはグローバルになることに注意しましょう。

```src/main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

/* eslint-disable no-new */
new Vue({
  el: '#app',
  components: { App },
  template: '<App/>'
})
```

# Hello Worldを改良してみよう
今回はHelloWorldにコンポーネントを追加してみましょう。QRコードを生成するコンポーネントとしてqriouslyというものが提供されています。このコンポーネントを外部から読み込んでみましょう!この場合にもyarnを使います。

`yarn add vue-qriously`

また導入したコンポーネントを配置します。HelloWorld.vueを導入する時には見慣れなかった一文として、src/App.vue内に書いた**Vue.use**があります。外部のvue.js用プラグインを導入する際には記述をします。なおtemplateにも配置をさすための一文が加わっていることに注意してください。

[Vue.use( )を書く場合と書かない場合
](https://qiita.com/fuqda/items/90073e3cd0987c82553d)


```src/App.vue
<template>
  <div id="app">
    <qriously value="Hello World!" :size="200" /> <!-- ここに コンポーネントを配置 -->
    <HelloWorld/>
  </div>
</template>

<script>
import Vue from 'vue'
import HelloWorld from './components/HelloWorld'
import VueQriously from 'vue-qriously' // 外部コンポーネントを読み込み

Vue.use(VueQriously) // Vue.use を使って外部のvue.js用コンポーネントを使いますと宣言!

export default {
  name: 'App',
  components: {
    HelloWorld,
    VueQriously //VueQriouslyをコンポーネント
  }
}
</script>
```


これでページを更新してみます。QRコードが表示されたら成功です。
<img width="837" alt="スクリーンショット 2019-04-14 13.22.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134021/43c0c203-a61d-4220-586e-987403174423.png">



# おわりに
今回の記事ではVUE.jsを使い始める環境の構築、VUE.jsの実行について触れました。また改良を加えるために最低限しておくべき内容をまとめました。細かな部分については本記事だけでカバーしきれないため、他の記事を参照していただきたく思います。次の記事ではコンポーネント間の値の受け渡しについての基礎、Vuexの導入、そしてWEBAPIを導入してフロントエンドとバックエンドの接続について触れたいと思います。

## 一連の連載
1. [初学者でもVue/Vuexを[確実に]動かせる記事~はじめてのHelloWorld~
](https://qiita.com/rerere0101/items/f799a60c4e505ff0e3d3)


2. [Vue.js初学者でも[確実に]ToDoアプリを動かしてVueコンポーネント間データ渡しを学ぶ(本記事)]
(https://qiita.com/rerere0101/items/6ac2889dc3a04566f9cc)