VueCLIでRouterとBootstrapを使う

#項目
1. `Router`を使う
1. `Bootstrap`を使える様にする

# 1.`Router`を使う
`Router`を使うと、スムーズなルーティングが出来る
まずはVueCLIプロジェクトを作業ディレクトリで起動する

```bash:
$ vue create vue-application

どのバージョンを使うか聞かれるので、manually select featuresを選択
その後使う機能選択が出るので、Routerをスペースで選択し、Enter

--------------------------------------------------------------------

バージョンを聞かれるので、とりあえずVueCLI3で
? Choose a version of Vue.js that you want to start the project with (Use arrow 
keys)
❯ 2.x 
  3.x

--------------------------------------------------------------------

これは"Y"を選択
? Use history mode for router? (Requires proper server setup for index fallback 
in production) (Y/n)

--------------------------------------------------------------------

この二つは続けてそのままEnter
? Pick a linter / formatter config: (Use arrow keys)
❯ 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)
❯◉ Lint on save
 ◯ Lint and fix on commit

--------------------------------------------------------------------

In Package.jsonを選択
? Where do you prefer placing config for Babel, PostCSS, ESLint, etc.? (Use arrow keys)
　 In dedicated config files
❯  In package.json

--------------------------------------------------------------------

ここで"Y"
? Save this as a preset for future projects? (y/N)

--------------------------------------------------------------------

なんやかんや出て大丈夫そうなら、作成したプロジェクトに移動してVueを起動してみる
$ cd vue-application
$ npm run serve
```
これで上の方に`Home/About`のあるWelcomページが表示されれば成功

## `Router`の中身について
### `src/main.js`

```javascript:
import { createApp } from 'vue'
import App from './App.vue'
//↓これが追加されている
import router from './router'

createApp(App).use(router).mount('#app')
```
特筆すべき点としては、`createApp(App).use(router).mount('#app')`で

- `createApp(App)`でVueインスタンスが作成され
- `.use(router)`で`Router`が使われると宣言され
- `.mount('#app')`で`id="app"`がVueで使われるよと言っている
- 所謂CDN版の`el: #app`みたいなもん

使うidを追加したい場合は似た様な形式で追記。

---
### `public/index.html`
ここは正直ほぼ触らない,<br>一つだけ重要なこととして

```html:
<div id="app"></div>
```
ここを上記で指定したidにしておく必要がある<br>それによってこの場所にvueで書かれた該当するテンプレートが表示されていく

---
### `src/router/index.js`
ルーティングに関するファイル

```javascript:
import { createRouter, createWebHistory } from 'vue-router'
//ここで ../views/Home.vueというPATH -> Homeに入れてる
import Home from '../views/Home.vue'

const routes = [
  {
    //ページが表示されるリンク
    path: '/',
    //以下二つで出力するファイル(Views配下)を指定
    name: 'Home',
    component: Home
  },
  {
    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.

    //↓で分かる通りviews/About.vueを表示するよと言っている
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

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

export default router
```
- `path`には`検索PATH`を
- `name`はここを利用して`検索PATH`を`router/index.js`のみで管理出来る<br>
後々紹介する`src/App.vue`にてページ遷移のためのリンクを下記の様に変更し、上記の事ができる(正直やらなくてもいいかも)

```vuejs:src/App.vue
<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <router-view/>
</template>

//これを

<template>
  <div id="nav">
    <router-link :to="{name:'Home'}">Home</router-link> |
    <router-link :to="{name:'About'}">About</router-link>
  </div>
  <router-view/>
</template>

//これでrouter/index.jsの中身のみでリンク操作が出来る
```
- `component`で`() => import(/* webpackChunkName: "about" */ 'views内の表示したいvueファイルPATH')`をする事で、どのファイルをそのリンクで表示するか選択をする<br>
また、`import Home from '../views/Home.vue'`の様にPATHを変数みたいにして選択しても良い

---
### `src/App.vue`
色々と表示する大元のファイル

```vuejs:
<!-- template内は全ルーティングに共通する要素を書く -->
<template>
  <div id="nav">
    <!-- どのルーティングでもHome | Aboutのリンクは表示されるので書いておく -->
    <!-- 初めは"/"が表示されるので特に指定する必要はない -->
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
　<!-- このrouter-viewでそれぞれのリンクに紐づいた内容を出力する -->
  <router-view/>
</template>

<!-- ここから下はCSS -->
<!-- ここも全体で共通するスタイルを書く -->
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>
```
基本的に覚えることとして、`App.vue`内は全ページで共通する物事を書く

- `<template>`内はhtmlを用いて共通するテンプレートを書く
 - `<router-link to="/">Home</router-link>`で`Router`に基づいたリンク先のルーティングが出来る
 - `<router-view/>`で上記で指定したリンク先の`views/`配下にあるファイルの内容を表示している
- `<style>`内は共通するCSSを書く

---

### `src/views/Home.vue (またはAbout.vue)`
ここは各々のルーティングに対応して表示するものが書かれたファイル

```vuejs:src/views/Home.vue
<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <!-- HelloWorldを下記で定義している -->
    <HelloWorld msg="Welcome to Your Vue.js App"/>
  </div>
</template>

<!-- ↓ここはjsを書く -->
<script>
// @ is an alias to /src
//ここで、後々説明する../components/HelloWorld.vueをHelloWorldという変数にしている
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  //nameはあまりよく分からない
  name: 'Home',
  components: {
    //ここで../components/HelloWorld.vueであるHelloWorldをタグとして使うよと言っている
    //ここに同じ要領で追加すると別のフロントエンドを組み合わせて出力出来る(あんまり使わない気もする)
    HelloWorld
  }
}
</script>
```
基本的にルーティングで指定された先のページについて書いてある<br>後々出てくる`../components/HelloWorld.vue`に表示したいことはほとんど書いてある

- `components/`配下が本当に本当のテンプレート
- まず`import 変数 from '@/components/vueファイル'`でファイルを取得し
- `export default{}`内で`components:{}`内に変数を置くことで、それがタグとして使用できる様になる
- その後`<script>`内で`<変数タグ>`を置くことで、その位置に指定されたファイルが出力される
- また変数のタグには`<HelloWorld msg="Welcome to Your Vue.js App"/>`の様に引数も渡せる
- 引数は指定ファイルにて`{{ msg }}`みたいな形で貰う
- 特に遷移の必要がなければここに本命のテンプレートを書いてもOK

---

### `src/components/HelloWorld.vue`
ここでやっと本命のテンプレートが出てくる

```vuejs:
<template>
  <div class="hello">
    //引数を受け取っている
    <h1>{{ msg }}</h1>
    <!-- 省略 -->
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    //ここで受け取った引数をstringとして取り出している
    msg: String
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<!-- ここで書いたcssはここでしか動かないよってこと -->
<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>
```
ほぼ書いてあるとおり<br>`App.vue -> views/Home.vue -> HelloWorld.vue`の順で上から来た引数を`props:{ 引数: データ型 }`で受け取れる<br>vueの親コンポーネントから子コンポーネントへ渡すものらしい

- CDN版の`data`や`methods`などは下記の様に`export default{}`配下で普通に使える

```vuejs:
<script>
export default {
  name: 'HelloWorld',
  props: {
    //ここで受け取った引数をstringとして取り出している
    msg: String
  },
  //data
  data: function() {
    //returnを入れるのを忘れない、ここだけ違う
    return {
      name: "次郎"
    }
  },
  //methods
  methods:{
      math_sum: function() {
        //ここは普通に書いて良さそう
        this.msg = "one"
      }
  }
}
</script>
```

---

## 動的なルーティング
`hello/1`、`hello/2`みたいな選択されたformによってのリンクでルーティング<br>まず動的なルーティングを作成する親ページにその元となる辞書を作成し、リンクを作る

```vuejs:
<template>
  <div class="hello">
    <div v-for="i in hello" :key="i.id">
        <!-- ${i.id}は文字列中の変数を意味する -->
        <router-link :to="`/hello/${i.id}`" title="${i.title}">
        {{ i.title }}
        </router-link>
      </div>
  </div>
</template>

<script>
export default {
  data(){
    return {
      hello: [
        {
          id:1,
          title:'Hello'
        },
        {
          id:2,
          title:'World'
        },
        {
          id:3,
          title:'hogehoge'
        }
      ]
    }
  }
}
</script>
```

これで辞書内にあるだけのリンクが動的に作成される

その後`router/index.js`にて

```vuejs:router/index.js
{
  //:idで上記の変数が来るよとしている
  path: '/hello/:id',
  name: 'hello',
  component: () => import(/* webpackChunkName: "about" */ '../views/hello.vue')
}
```
これでルーティング先の動的な指定が完了した。<br>その後上で指定した`hello.vue`にて

```vuejs:hello.vue
<template>
  <div class="hello_show">
    {{title}}
  </div>
</template>

<script>
export default {
  name: 'HelloWorldhugahuga',
  props: {
    //ここで受け取った引数をstringとして取り出している
    title: String
  }
}
</script>
```
これで受け取った`title`を動的に表示している

# 2.`Bootstrap`を使える様にする
作業ディレクトリで

```bash:
$ npm install --save bootstrap
```
した後、`src/main.js`に

```vuejs:src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

//↓こいつを書き加える
import "bootstrap/dist/css/bootstrap.min.css"

createApp(App).use(router).mount('#app')
```
あとは適当なテンプレートに

```vuejs:
<template>
  <button type="button" class="btn btn-success">Success</button>
</template>
```
これ書いて表示されれば終了