VueCLIでアプリ作成(アドレス帳)①

プロジェクト作成

vue create udemy-sample

プロジェクトフォルダに移動してnpm run serveするとVue.jsのサーバが起動。デフォルトで8080ポートが使われる。

http://localhost:8080/でデフォルトのVue.jsの画面がでてればOK

publicディレクトリ内がドキュメントルートとして公開されます。

アドレスの一覧表示をする単一ファイルコンポーネント作成

src/components/Addresses.vue

<template>
 <div>
   <h1>マイアドレス帳</h1>
 </div>
</template>

<script>
</script>

<style scopedlang="scss">
</style>

まずはこれを表示させます。

表示関係のファイルはsrc/viewsフォルダ

src/views/Home.vueの内容が表示されているので、これを書き換えてローカル登録する。

<template>
 <div class="home">
   <Addresses></Addresses>  //←ここsrc/components/Addresses.vueの内容が表示
 </div>
</template>

<script>
// @ is an alias to /src
import Addresses from '@/components/Addresses.vue' //←src/components/Addresses.vue読込

export default {
 name: 'Home',
 components: {
   Addresses //←ローカル登録
 }
}
</script>

①Addresses.vueをインポート。コメントにもあるように@が/srcを示しているので。@/components/~と記述すればよい。

②componentsにAddressesを登録

③template内の表示させたいところに<Addresses />タグをいれる

無題

こんな表示になっていればOK

Vue Routerで画面の切り替え

src/main.jsでrouterをimportして、router変数にrouterを渡している。

実際の動きとして記述する方法は、

①src/router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue' //←importで読み込む場合

Vue.use(VueRouter)

const routes = [
  {
   path: "/",
   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.
   component: () =>
     import(/* webpackChunkName: "about" */ "../views/About.vue"),
 },
]

const router = new VueRouter({
 mode: 'history',
 base: process.env.BASE_URL,
 routes
})

export default router

②src/App.vue

      <router-link to="/">Home</router-link> |  //←書き方①
      <router-link to="/about">About</router-link>
      
      <router-link to="{ name: 'Home' }">Home</router-link> | //←書き方②
      <router-link to="{ name: 'About' }">About</router-link>
   </div>
   <router-view/> //←ここでコンポーネントが書き出される
   
   <!--共通パーツはrouter-viewの外に書く---->

vutify導入

vue add vuetify

npm run serveすると画面変更されていればOK

src/App.vue でホーム画面を整理。

<template>
 <v-app>
   <v-toolbar app>
     <v-toolbar-side-icon></v-toolbar-side-icon> //←メニューアイコン追加
     <v-toolbar-title class="headline text-uppercase">
       <span>マイドレス帳</span> //←ツールバーのタイトル
     </v-toolbar-title>
     <v-spacer></v-spacer>
   </v-toolbar>

   <v-content>
     <Addresses/> //←先に作成したAddresses.vueを憑依
   </v-content>
 </v-app>
</template>

<script>
import Addresses from './components/Addresses.vue' //←Addresses.vueをimport

export default {
 name: 'App',
 components: {
   Addresses //←Addresses.vueを登録
 },
 data () {
   return {
     //
   }
 }
}
</script>

無題

ナビゲーション追加

①src/components/SideNav.vueを作成

<template>
 <v-layout wrap style="height: 200px;">

   <v-container>
     <v-layout justify-center>
        <!-- ▼drawerの値の変更 @click.stop="drawer = !drawerでboolの値反転させる -->
       <v-btn color="pink" dark @click.stop="drawer = !drawer">Toggle</v-btn>
     </v-layout>
   </v-container>
    
   <!-- ▼navの開閉 v-model="drawer"  dataで初期はdrawer: false,-->
   <v-navigation-drawer v-model="drawer" absolute temporary>
     <v-list class="pa-1">
       <v-list-tile avatar>
         <v-list-tile-avatar>
           <img src="https://avatars2.githubusercontent.com/u/1363954?s=460&v=4">
         </v-list-tile-avatar>

         <v-list-tile-content>
           <v-list-tile-title>Kazuya Kojima</v-list-tile-title>
         </v-list-tile-content>
       </v-list-tile>
     </v-list>

     <v-list class="pt-0" dense>
       <v-divider></v-divider>

       <v-list-tile v-for="item in items" :key="item.title">
         <v-list-tile-action>
          <!-- ▼マテリアルアイコン data{ title: '連絡先一覧', icon: 'list' } リストアイコンを指定 -->
           <v-icon>{{ item.icon }}</v-icon>
         </v-list-tile-action>

         <v-list-tile-content>
           <v-list-tile-title>{{ item.title }}</v-list-tile-title>
         </v-list-tile-content>
       </v-list-tile>
     </v-list>
   </v-navigation-drawer>
 </v-layout>
</template>

<script>
export default {
 data () {
   return {
     drawer: false,
     items: [
       { title: '連絡先一覧', icon: 'list' }
     ]
   }
 }
}
</script>

マテリアルアイコンについてはこちら

https://fonts.google.com/icons

②App.vueで登録とタグを挿入

<template>
 <v-app>
   <v-toolbar app>
     <v-toolbar-side-icon></v-toolbar-side-icon>
     <v-toolbar-title class="headline text-uppercase">
       <span>マイドレス帳</span>
     </v-toolbar-title>
     <v-spacer></v-spacer>
   </v-toolbar>
   <SideNav></SideNav> //←タグを挿入

   <v-content>
     <Addresses/>
   </v-content>
 </v-app>
</template>

<script>
import Addresses from './components/Addresses.vue'
import SideNav from './components/SideNav.vue' //←import 

export default {
 name: 'App',
 components: {
   Addresses,
   SideNav //←登録
 },
 data () {
   return {
     //
   }
 }
}
</script>

無題

Vuexとは

①ストアというデータの入れ物を作り、各コンポーネントからアクセスしてデータの出し入れをできるようにする。
②Action,Mutation,State,Getterで構成(stateがデータをいれるところ)
③基本的にはアプリケーションで1つのストアを持つ

コンポーネントはデータを受け取る時はstateから直接取得するか、getterを通じて取得する

Vuexのストア実装

Vue CLIインストール時にVuexもインストールしておく。

src/sotre/index.js

import Vue from "vue";
import Vuex from "vuex";

Vue.use(Vuex);

export default new Vuex.Store({
 state: {
   drawer: false,
 },
 mutations: {
   toggleSideMenu(state) {
     state.drawer = !state.drawer;
   },
 },
 actions: {
   toggleSideMenu({ commit }) {
     commit("toggleSideMenu");
   },
 },
 modules: {},
});

①toggleSideMenuの引数としてcommitメソッドを受け取る。
(アクションメソッドの引数には自動的にcontextオブジェクトがわたってきます。これはcontext.commitメソッドだけを受け取る記述方法)
actions: {
toggleSideMenu({ commit }) {
commit("toggleSideMenu");
},
},


②commitでmutationのメソッドを指定 commit("toggleSideMenu");

・mutation自動的にstateがわたってくるので、ここでstateの値を更新させる

mutations: {
toggleSideMenu(state) {
state.drawer = !state.drawer;
},
},

ストアの利用

メニューアイコンにトグル機能を実装させる。$storeでアクセスできるようになります。ストアのデータ(ストアのステート)には$store.state.でアクセス。

src/components/SideNav.vueを修正

①トグルボタンを削除(メニューアイコンから開閉するため)

②dataのdrawerは削除(ストアのstateを利用するため)

③v-model="drawer"を変更(ストアのstate.drawerに変更)

//▼削除
    <v-container>
     <v-layout justify-center>
       
       <v-btn color="pink" dark @click.stop="drawer = !drawer">Toggle</v-btn>
     </v-layout>
   </v-container>
   
   //▼削除 script data
   drawer: false,
   
   //▼v-model="drawer"をv-model="$store.state.drawer"に変更
   <v-navigation-drawer v-model="$store.state.drawer" absolute temporary>

これで$store.state.drawerをコントロールできる状態になった。
(SideNav.vueとsrc/App.vueのツールバーアイコンが紐づいていない)

src/App.vueでアイコンにクリックメソッド実装

ストア($store)はdispatchメソッドを保有していて、store/index.jsで設定したtoggleSideMenuアクションを呼び出します。

  methods:{
   openSideMenu(){
     this.$store.dispatch('toggleSideMenu')
   }
 }

ツールバーアイコンにクリックメソッド実装

<v-toolbar-side-icon @click="openSideMenu"></v-toolbar-side-icon>
   
<template>
 <v-app>
   <v-toolbar app>
     <v-toolbar-side-icon @click="openSideMenu"></v-toolbar-side-icon>
     <v-toolbar-title class="headline text-uppercase">
       <span>マイドレス帳</span>
     </v-toolbar-title>
     <v-spacer></v-spacer>
   </v-toolbar>
   <SideNav></SideNav>

   <v-content>
     <Addresses/>
   </v-content>
 </v-app>
</template>

<script>
import Addresses from './components/Addresses.vue'
import SideNav from './components/SideNav.vue'

export default {
 name: 'App',
 components: {
   Addresses,
   SideNav
 },
 data () {
   return {
     //
   }
 },
 methods:{
   openSideMenu(){
     this.$store.dispatch('toggleSideMenu')
   }
 }
}
</script>

  

いいなと思ったら応援しよう!