Vueハンズオン用ドキュメント。
インストール〜APIリクエスト、テーブル操作までやってみる。
インストール
- Node.js
Mac
$ brew update
# nodebrew インストール
$ brew install nodebrew
$ mkdir -p ~/.nodebrew/src
# node.js インストール
$ nodebrew install-binary stable
## 確認
$ nodebrew ls
v12.16.1
## 適用
$ nodebrew use v12.16.1
## 環境パス適用(zsh用)
$ echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zshrc
$ source ~/.zshrc
## node確認
$ node -v
v12.16.1
Windows
下記手順に沿ってインストール
Node.jsバージョンの指定はありません
- Vue CLI
$ npm install -g @vue/cli
## Version確認
$ vue --version
@vue/cli 4.2.2
最新版のインストールでOK
Vueハンズオン
1.プロジェクト作成と起動
$ vue create my-vue-project
? Please pick a preset: (Use arrow keys)
❯ default (babel, eslint)
Manually select features
## 確認
$ cd my-vue-project
$ ls -lrt
total 928
-rw-r--r-- 1 usami65 staff 73 3 29 14:41 babel.config.js
drwxr-xr-x 4 usami65 staff 128 3 29 14:41 public
drwxr-xr-x 6 usami65 staff 192 3 29 14:41 src
-rw-r--r-- 1 usami65 staff 843 3 29 14:41 package.json
drwxr-xr-x 822 usami65 staff 26304 3 29 14:41 node_modules
-rw-r--r-- 1 usami65 staff 460067 3 29 14:41 package-lock.json
-rw-r--r-- 1 usami65 staff 326 3 29 14:41 README.md
## 起動
$ npm run serve
## 確認
http://localhost:8080/
2.Bootstrap Vue
- Bootstrap Vueインストール
$ vue create my-first-bootstrap-project
$ cd my-first-bootstrap-project
$ npm install bootstrap-vue bootstrap
- エントリーポイント(
src/main.js
)へbootstrapを登録
import Vue from 'vue'
import App from './App.vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// Install BootstrapVue
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.config.productionTip = false
- bootstrap使ってみる(Form input)
# src/App.vue
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
<hr />
<div>
<b-form-input v-model="text" placeholder="Enter your name"></b-form-input>
<div class="mt-2">Value: {{ text }}</div>
</div>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components: {
HelloWorld
},
data() {
return {
text: ''
}
}
}
</script>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
入力フィールドあるはず!!
3.APIリクエスト
- axiosインストール
$ vue create my-first-axios-project
$ cd my-first-axios-project
$ npm install axios
- エントリーポイント(
src/main.js
)へbootstrapを登録
import Vue from 'vue'
import App from './App.vue'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// Install BootstrapVue
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.config.productionTip = false
- APIリクエスト(Get)を書いてみる
src/App.vue
の内容を下記へ書き換える
<template>
<div>
<br>
<b-button variant="outline-primary" @click="getIp">IPを取得</b-button>
<hr/>
<div>Your IP: {{ ipAddress }}</div>
<br>
<div>Json Data: {{ jsonData }}</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'TestAPP',
data() {
return {
jsonData: '',
ipAddress: '',
}
},
methods: {
getIp() {
const url = 'https://httpbin.org/get';
axios.get(url)
.then((response) => {
console.log(response.data);
this.jsonData = response.data;
this.ipAddress = response.data.origin;
})
.catch((e) => {
alert(e);
});
}
}
}
</script>
<style scoped>
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
IPを取得
ボタンを押すとIPアドレスが表示される。
4.テーブル
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- テーブルデータ コンポーネント作成
src/components/HandsOn.vue
の内容を下記へ書き換える
<template>
<div>
<table border="1">
<tr>
<td>{{items[0].age}}</td>
<td>{{items[0].first_name}}</td>
<td>{{items[0].last_name}}</td>
</tr>
<tr>
<td>{{items[1].age}}</td>
<td>{{items[1].first_name}}</td>
<td>{{items[1].last_name}}</td>
</tr>
<tr>
<td>{{items[2].age}}</td>
<td>{{items[2].first_name}}</td>
<td>{{items[2].last_name}}</td>
</tr>
</table>
</div>
</template>
<script>
export default {
name: 'HandsOn',
data() {
return {
items: [
{age: 40, first_name: 'Dickerson', last_name: 'Macdonald'},
{age: 21, first_name: 'Larsen', last_name: 'Shaw'},
{age: 89, first_name: 'Geneva', last_name: 'Wilson'},
]
}
}
}
</script>
<style scoped>
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
5.テーブル(Bootstrap)
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- テーブルデータ コンポーネント作成
src/components/HandsOn.vue
の内容を下記へ書き換える
<template>
<div>
<b-table striped hover :items="items"></b-table>
</div>
</template>
<script>
export default {
data() {
return {
items: [
{ age: 40, first_name: 'Dickerson', last_name: 'Macdonald' },
{ age: 21, first_name: 'Larsen', last_name: 'Shaw' },
{ age: 89, first_name: 'Geneva', last_name: 'Wilson' },
]
}
}
}
</script>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
- 参考
6.複数コンポーネント
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- コンポーネント作成
src/components/HandsOn1.vue
<template>
<div>
Hands on 1
</div>
</template>
<script>
export default {
name: 'HandsOn1',
}
</script>
<style scoped>
</style>
src/components/HandsOn2.vue
<template>
<div>
Hands on 2
</div>
</template>
<script>
export default {
name: 'HandsOn1',
}
</script>
<style scoped>
</style>
- 複数コンポーネント参照
src/App.vue
<template>
<div id="app">
<HandsOn1></HandsOn1>
<br>
<HandsOn2></HandsOn2>
</div>
</template>
<script>
import HandsOn1 from "./components/HandsOn1";
import HandsOn2 from "./components/HandsOn2";
export default {
name: 'App',
components: {
HandsOn1,
HandsOn2
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
7.Props(親コンポーネントから子コンポーネントへの値渡し)
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- 子コンポーネント
src/components/HandsOn3.vue
<template>
<div>
Hands on 3
<hr>
{{msg}}
</div>
</template>
<script>
export default {
name: 'HandsOn2',
props: {
msg: { type: String, default: '' },
},
}
</script>
<style scoped>
</style>
- 親コンポーネント
src/App.vue
<template>
<div id="app">
<HandsOn1></HandsOn1>
<br>
<HandsOn2></HandsOn2>
<br>
<HandsOn3 msg="テストメッセージ"></HandsOn3>
</div>
</template>
<script>
import HandsOn1 from "./components/HandsOn1";
import HandsOn2 from "./components/HandsOn2";
import HandsOn3 from "./components/HandsOn3";
export default {
name: 'App',
components: {
HandsOn1,
HandsOn2,
HandsOn3,
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
8.ルーティング
コンポーネントのルーティング。URLの動的変更。
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- vue-routerインストール
$ cd vue-hanson-project
$ npm install vue-router
- ルーティング用 コンポーネント1
src/HandsOn.vue
<template>
<div>
HandsOn
</div>
</template>
<script>
export default {
name: "HandsOn"
}
</script>
<style scoped>
</style>
- ルーティング用 コンポーネント2
src/HandsOn2.vue
<template>
<div>
HandsOn2
</div>
</template>
<script>
export default {
name: "HandsOn2"
}
</script>
<style scoped>
</style>
- ルーティング用 コンポーネント3
src/HandsOn2.vue
<template>
<div>
HandsOn3
</div>
</template>
<script>
export default {
name: "HandsOn3"
}
</script>
<style scoped>
</style>
- vue-router 設定
src/router/index.js
import Vue from 'vue'
import Router from 'vue-router'
import HandsOn from "../components/HandsOn";
import HandsOn2 from "../components/HandsOn2";
import HandsOn3 from "../components/HandsOn3";
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'HandsOn',
component: HandsOn
},
{
path: '/2',
name: 'HandsOn2',
component: HandsOn2
},
{
path: '/3',
name: 'HandsOn3',
component: HandsOn3
},
]
})
-
main.js
への反映
src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
// Install BootstrapVue
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App),
}).$mount('#app')
- ルーティングコントロール コンポーネント
src/App.vue
<template>
<div id="app">
<div class="link-container">
<router-link class="link" :to="{ name: 'HandsOn' }">HansOn</router-link>
<router-link class="link" :to="{ name: 'HandsOn2' }">HansOn2</router-link>
<router-link class="link" :to="{ name: 'HandsOn3' }">HansOn3</router-link>
</div>
<hr>
<router-view/>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.link-container {
display: flex;
flex-direction: row;
}
.link {
margin-left: 20px;
}
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
9. Vueライフサイクルフック
ロード時に処理してみよう
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- ロード時にフックするコンポーネント
src/components/HandsOn.vue
<template>
<div>
<div v-if="ipAddress">
<div>Your IP: {{ ipAddress }}</div>
<hr>
<div>Json Data: {{ jsonData }}</div>
</div>
<div v-else>
<b-spinner variant="primary"></b-spinner>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: "HandsOn",
data() {
return {
jsonData: '',
ipAddress: '',
}
},
created() {
// spinner確認のために意図的に1秒遅延
setTimeout(() => this.setIp(), 1000);
},
methods: {
setIp() {
const url = 'https://httpbin.org/get';
axios.get(url)
.then((response) => {
console.log(response.data);
this.jsonData = response.data;
this.ipAddress = response.data.origin;
})
.catch((e) => {
alert(e);
});
}
},
}
</script>
<style scoped>
</style>
src/App.vue
の内容を下記へ書き換える
<template>
<div id="app">
<HandsOn></HandsOn>
</div>
</template>
<script>
import HandsOn from "./components/HandsOn";
export default {
name: 'App',
components: {HandsOn},
comments: {
HandsOn
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</style>
- 確認
## 起動
$ npm run serve
## 確認
http://localhost:8080/
10. グラフ描画
11. Vuex
結構難しい!!
データの状態管理一元化を行う
使用例:
- 認証用Tokenの保持や再利用
- 複数コンポーネント間でのデータ管理
- 永続的なデータ保持(ブラウザが有効な限り)
参考:
https://qiita.com/fruitriin/items/42b0ebc5f8a524a0ae17
12. ルーティング(ナビゲーションガード)
ページ(コンポーネント)のアクセス可否コントロール
Token認証等で利用
13. VueをDockerで公開する
docker-composeを利用してVueをDockerで公開しよう
前提:
dockerインストール済み
docker-composeインストール済み
作業用プロジェクトをgit clone
する
$ git clone https://github.com/65usami/vue-hanson-project.git
- Dockerfileの作成
vue-hanson-project/Dockerfile
を作成
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;","-c","/etc/nginx/nginx.conf"]
- docker-compose.ymlの作成
vue-hanson-project/docker-compose.yml
を作成
version: '3.7'
services:
web:
build: .
ports:
- '80:80'
- 確認
## 起動
$ docker-compose up
## 確認
http://localhost