0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vueハンズオン

Last updated at Posted at 2020-04-21

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

参考: https://cli.vuejs.org/

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/

入力フィールドあるはず!!

参考: https://bootstrap-vue.js.org/docs/components/form-input

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/
  • 参考

bootstrap-vue

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

結構難しい!!

データの状態管理一元化を行う

vuex-6-638.jpg

使用例:

  • 認証用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
0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?