LoginSignup
6
9

More than 3 years have passed since last update.

Vue CLIで新規プロジェクト作成と、よくある雛形の実装

Last updated at Posted at 2019-12-31

Vue CLIで新規プロジェクト作成と、よくある雛形の実装

この記事はサーバーレスWebアプリ Mosaicを開発して得た知見を振り返り定着させるためのハンズオン記事の1つです。

以下を見てからこの記事をみるといい感じです。

はじめに

Vue CLI 3でSPA(シングルページアプリケーション)の雛形を新規作成します。
UI用のフレームワークとして、マテリアルデザインのVuetifyを利用。
ヘッダー、フッター、いくつかのページへのルーティング、ハンバーガーメニューなどを実装します。

コンテンツ

GithubにWebアプリプロジェクト用のリポジトリを作成

リポジトリ名は sample_vue_project とします。
Vueのプロジェクト名と同じにしますので、大文字は使えません。

Cloud9にリポジトリをクローン

$ git clone https://github.com/{YourGithubID}/sample_vue_project.git

Vueプロジェクトの作成

以下のコマンドで新規プロジェクトを作成できます。

$ vue create sample_vue_project

プロジェクト作成が終わるとこんな感じになってると思います。
Screenshot 2019-12-22 at 23.02.44.png

  • Vueプロジェクト実行
    Cloud9でVueのプロジェクトを実行するために、プロジェクトディレクトリ直下に以下のファイルが必要です。
vue.config.js
module.exports = {
  "devServer": {
    host: '0.0.0.0',
    public: '0.0.0.0:8080',
    disableHostCheck: true
  }
}

(※理由は良く知りません、、。誰か教えて下さい。)
@NonbiriTarsan さんが情報を提供してくださいました。(2020.1.27)
---ここから---
こちらのサイトによりますと、上に書いた設定disableHostCheck:trueだと、根本的な解決ではないそうで、以下のような設定とするべきだそうです。

vue.config.js
module.exports = {
    devServer: {
        public: "${$C9_PID}.vfs.cloud9.${MY_REGION}.amazonaws.com"
    }
}

${MY_REGION}はいいと思いますが、${$C9_PID}が何か少し迷いました。
Cloud9の環境詳細にある、Environment ARN
arn:aws:cloud9:ap-northeast-1:123456789012:environment:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
これの、xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxの部分がソレです。

なるほどなるほど、、、って、
前の設定と後の設定で、何がどう変わるのか、正直理解しきれていないのですが、そういう事みたいです。
---ここまで---

プロジェクトディレクトリで以下のコマンドにより、プロジェクトのビルドの後にサーバーが起動して、Webアプリにアクセスできるようになります。

$ npm run serve

ビルドが終わりサーバーが起動したら、上部メニューバーにある Preview > Preview Running Application からアクセスしてください。
Screenshot 2019-12-22 at 23.58.31.png
こんな感じのVueのWelcome画面が表示されればOKです。
右上の方にある Pop Out Into New Window によりブラウザの別タブで開くことができ、またそうすることでデベロッパーツールも利用できるようになります。
Screenshot 2019-12-23 at 00.00.44.png

起動したサーバーは、Ctrl+Cで停止できます。

Vuetifyの利用

プロジェクトディレクトリで以下のコマンドにより、Vuetifyをプロジェクトにインストールすることができます。

$ vue add vuetify
? Choose a preset: Default (recommended)

インストールできたら実行してみてください。デザインがVuetifyのものに変わっています。
Screenshot 2019-12-25 at 21.07.59.png

いくつかのページとページ遷移のためのルーティング

ページ遷移のために、ルーティング制御プラグインVue Routerを利用します。
まずはインストールします。

$ npm install vue-router

必要な画面分、ViewとComponentのvueファイルを作成します。
ここではHomeとAboutの2画面作成し、また、お互いの画面を行き来できるようにしておきます。

以下のファイルを新規作成します。
src/views/Home.vue
src/views/About.vue
src/components/Home.vue
src/components/About.vue
src/router.js

最初からある以下のファイルは削除します。
src/components/HelloWorld.vue

  • ソースコードの更新
src/view/Home.vue
<template> 
  <Home /> 
</template> 

<script> 
  import Home from '../components/Home'  
  export default { 
    components: { 
      Home 
    } 
  } 
</script> 
src/view/About.vue
<template> 
  <About /> 
</template> 

<script> 
  import About from '../components/About' 
  export default { 
    components: { 
      About 
    } 
  } 
</script> 
src/components/Home.vue
<template>
  <v-container>
    <p>ホーム</p>
    <router-link to="about" >link to About</router-link>
  </v-container>
</template>
src/components/About.vue
<template>
  <v-container>
    <p>アバウト</p>
    <router-link to="/" >link to Home</router-link>
  </v-container>
</template>
src/router.js
import Vue from 'vue'; 
import Router from 'vue-router'; 
import Home from './views/Home.vue'; 
import About from './views/About.vue'; 

Vue.use(Router); 

export default new Router({ 
  routes: [ 
    { 
      path: '/', 
      name: 'home', 
      component: Home,
    }, 
    { 
      path: '/about', 
      name: 'about', 
      component: About, 
    }, 
  ] 
});
src/main.js
import Vue from 'vue'
import App from './App.vue'
import vuetify from './plugins/vuetify';
import router from './router';

Vue.config.productionTip = false

new Vue({
  vuetify,
  router, 
  render: h => h(App)
}).$mount('#app')
src/App.vue
<template>
  <v-app>
    <v-content>
      <router-view></router-view>
    </v-content>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  components: {
  },
  data: () => ({
    //
  }),
};
</script>

(※JavaScript、Vue.js、Vuetifyの基本構文についてはここでは触れません。必要な場合はどこかで学んできてください。)

実行してみましょう。
お互いのページを行き来するだけのシンプルなSPAが実行できました。
Screenshot 2019-12-29 at 07.53.05.png

ヘッダーとフッター

見た目が寂しいのでヘッダーとフッターを付けましょう。

src/App.vue
<template>
  <v-app>
    <v-app-bar app>
      <v-toolbar-title>
        Sample Vue Project
      </v-toolbar-title> 
    </v-app-bar>

    <v-content>
      <router-view></router-view>
    </v-content>

    <v-footer app>
      <v-card-title>
        <v-btn fab small class="mx-2" color="white" href="https://twitter.com/w2or3w" target="_blank">
          <v-icon>mdi-twitter</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.facebook.com/w2or3w" target="_blank">
          <v-icon>mdi-facebook</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.instagram.com/w2or3w" target="_blank">
          <v-icon>mdi-instagram</v-icon>
        </v-btn>
      </v-card-title>
      <v-card-text>
        <p>Copyright © Sample Vue Project</p>
      </v-card-text>
    </v-footer>
  </v-app>
</template>

<script>
export default {
  name: 'App',
  components: {
  },
  data: () => ({
    //
  }),
};
</script>

ヘッダー(v-app-bar)とフッター(v-footer)を加えました。

実行してみましょう。
ヘッダーとフッターが付いてそれっぽくなりましたね。
(※SNSリンクはワタシのものなので自分のものに変えてくださいね。(フォロー歓迎です。))
Screenshot 2019-12-29 at 09.56.30.png

ハンバーガーメニュー

これも最近のサイトには良くありがちなハンバーガーメニューを付けてきましょう。

src/App.vue
<template>
  <v-app>
    <v-navigation-drawer app v-model="drawer">
      <v-list nav dense>
        <v-list-item-group>
          <v-list-item>
            <v-list-item-title @click="onHome">HOME</v-list-item-title>
          </v-list-item>
          <v-list-item>
            <v-list-item-title @click="onAbout">ABOUT</v-list-item-title>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>

    <v-app-bar app>
      <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
      <v-toolbar-title>
        Sample Vue Project
      </v-toolbar-title> 
    </v-app-bar>

    <v-content>
      <router-view></router-view>
    </v-content>

    <v-footer app>
      <v-card-title>
        <v-btn fab small class="mx-2" color="white" href="https://twitter.com/w2or3w" target="_blank">
          <v-icon>mdi-twitter</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.facebook.com/w2or3w" target="_blank">
          <v-icon>mdi-facebook</v-icon>
        </v-btn>
        <v-btn fab small class="mx-2" color="white" href="https://www.instagram.com/w2or3w" target="_blank">
          <v-icon>mdi-instagram</v-icon>
        </v-btn>
      </v-card-title>
      <v-card-text>
        <p>Copyright © Sample Vue Project</p>
      </v-card-text>
    </v-footer>

  </v-app>
</template>

<script>
export default {
  name: 'App',
  components: {
  },
  data: () => ({
    drawer: false,
  }),
  methods:{
    onHome() {
      if(this.$route.path != '/'){
        this.$router.push({ path: '/' });
      }
    }, 

    onAbout() {
      if(this.$route.path != '/about'){
        this.$router.push({ path: 'about' });
      }
    }, 
  }
};
</script>

メニュー本体(v-navigation-drawer)と、v-app-barにアイコン(v-app-bar-nav-icon)を加えました。また、dataにdrawerフラグも追加しています。

実行してみましょう。
ハンバーガーメニューが付きましたね。
Screenshot 2019-12-29 at 09.56.47.pngScreenshot 2019-12-29 at 09.57.03.png

あとがき

ここで作成したプロジェクトはGitHubの以下に置いておきますね。
https://github.com/ww2or3ww/sample_vue_project/tree/work1

UIデザイン(見た目)ってすごく大事だと思うのですが、実装するにあたってすごく面倒だし消耗させられる部分でもあります。
CSS完全に理解したTシャツがバズってましたが、そういう事ですよね。
EEzpN-JU0AA7u4z.jpeg

VuetifyやBulmaのようなUIフレームワークを利用することで、UIデザインにあまり消耗せず、デフォルトでそれっぽく仕上げることができますのでとても助かります。
ワタシはGoogleが好きなので、Googleが推しているMaterial Designを継承しているVuetifyを選びました。

このハンズオン記事では、極力CSSは書かない方針でいきたいと思いますのでよろしくお願いします。

とはいえ、思い入れをもってアプリを作ろうとしたときにデザインは避けて通れません。UIフレームワークを利用した上で、こだわりという名の微調整をCSSでチマチマとする羽目になるでしょう。

最後に、デザインのために役立つサイトを置いておきますね。
配色に悩んだららここを参照すべし。
アイコンはここで探しています。
マテリアルデザインのホームは、見てるだけで楽しいです。

6
9
2

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
6
9