Vue でダッシュボードの雛形を作る最速の道

今回の最速はたぶん煽りではありません。
ただ、最速だけだと記事も最短になってしまうので、Vue CLI 3 を使ってマニュアルで仕立てる手も紹介します。

この記事は MacOS 10.14.2 で検証してあります。

# 準備1

[ Node.js と npm を用意します。](https://nodejs.org/ja/) 


# 最速の道

## 雛形のダウンロード

[ Creative Tim のホームページから Vuetify Material Dashboard をダウンロードします。](https://www.creative-tim.com/product/vuetify-material-dashboard?ref=vuetifyjs.com)
（無料ですが登録が必要です。）

## 実行

ダウンロードした zip を解凍したフォルダに入って

```
$ npm i
$ npm run dev
```
として、ブラウザで

[localhost:8080](http://localhost:8080)

にアクセスすれば以下の画面が表示されます。


![スクリーンショット 2019-02-08 2.16.02.png](https://qiita-image-store.s3.amazonaws.com/0/73493/1ccfa52c-3853-d429-f3ba-bd87b2af08b0.png)

## カスタマイズ

あとは上記フォルダの中の src フォルダ以下を弄っていけばいいです！


# マニュアルで仕立てる道

## 準備2

## Vue CLI 3 のインストール

もし vue-cli の昔のバージョンを使っていたら、アンインストールします。

```
$ npm uninstall -g vue-cli
```


Vue CLI 3 をグローバルにインストールします。

```
$ npm i -g @vue/cli
```

## プロジェクトの作成

例として、experimental という名前でプロジェクトを作成します。選択肢がでてきます。

```
$ vue create experimental

Vue CLI v3.4.0
? Please pick a preset: 
  default (babel, eslint) 
❯ Manually select features 
```

Manually select features を選択します。

```
Vue CLI v3.4.0
? Please pick a preset: Manually select features
? Check the features needed for your project: 
 ◯ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
❯◉ Router
 ◉ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing
```

あとで間違いなく必要になるので、Router と Vuex を選択します。他のは説明の都合上はずします。必要だったら後から入れられます。

```
Vue CLI v3.4.0
? Please pick a preset: Manually select features
? Check the features needed for your project: Router, Vuex
? Use history mode for router? (Requires proper server setup for index fallback in
 production) (Y/n) 
```
いろいろ聞いてきますが、デフォルトで進めます。

プロジェクト名（ここでは experimental）のフォルダが作成されます。また自動的に .git も作られて git で管理できるようになります。

次の作業のために、できたフォルダに入ります。

```
$ cd experimental
```

## プロジェクトに Vuetify を入れる。

コンポーネントライブラリを使えば開発をとても早く進められます。今回は Vuetify を入れます。

Vuetify を入れるには、コマンドラインでやる方法と GUI でやる方法があります。

### コマンドラインでやる方法

```
$ vue add vuetify
```

とやるだけです。簡単ですね！

### GUI を使う方法

Vue CLI 3 からブラウザを GUI に使ってプロジェクトを管理できるようになりました。使わない手はありません。

```
$ vue ui
```

とやると、ブラウザが開いてプロジェクト一覧が表示されます。

![スクリーンショット 2019-02-08 2.47.36.png](https://qiita-image-store.s3.amazonaws.com/0/73493/e99f678e-f477-e936-c9fe-0e1ad9df16d7.png)

Import タブを選んで、Import this folder ボタンを押します。

![スクリーンショット 2019-02-08 2.49.56.png](https://qiita-image-store.s3.amazonaws.com/0/73493/2166bef2-ec7a-b7b7-89b2-d1ac50bae80d.png)

プロジェクトのダッシュボードが表示されます。

![スクリーンショット 2019-02-08 2.53.37.png](https://qiita-image-store.s3.amazonaws.com/0/73493/2b9e085d-859f-e8c6-81f7-d167ff51c785.png)

左側の上から2つめのプラグインボタンを押すと現在インストールされてるプラグインが表示されます。

![スクリーンショット 2019-02-08 3.53.18.png](https://qiita-image-store.s3.amazonaws.com/0/73493/a1858259-c0ff-366b-3281-c74c156ce97c.png)

右上の Add Plugin ボタンを押して、サーチフィールドに vuetify と入力します。

![スクリーンショット 2019-02-08 2.58.17.png](https://qiita-image-store.s3.amazonaws.com/0/73493/258a5f4f-cc19-c12d-e994-e6726bddb562.png)

一番上の vue-cli-plugin-vuetify を選択して右下の install ボタンを押します。

![スクリーンショット 2019-02-08 2.59.59.png](https://qiita-image-store.s3.amazonaws.com/0/73493/df278080-bd34-a98f-a633-6b645979181a.png)

Finish Installation を押せばなんと Git の差分の画面になります。コミットするなりスキップするなりしましょう


![スクリーンショット 2019-02-08 3.06.35.png](https://qiita-image-store.s3.amazonaws.com/0/73493/c2b9bbac-ed77-ef0e-9c55-a8d3d6cc831f.png)

無事 Vuetify がインストールできました。
![スクリーンショット 2019-02-08 3.55.21.png](https://qiita-image-store.s3.amazonaws.com/0/73493/fcea10ed-0f52-1c67-b70a-f65f4141ea29.png)

## 一旦実行

```
$ npm run serve
```

とすると、サービスが始まります。
ブラウザで[ localhost:8080 ](http://localhost:8080)にアクセスすると、以下の画面になり、Vuetify がインストールできたことが確認できます。

![スクリーンショット 2019-02-08 3.11.29.png](https://qiita-image-store.s3.amazonaws.com/0/73493/3fd350cf-cd11-af26-3085-eae31585098b.png)

## ダッシュボード化

ここからが本題です。

![スクリーンショット 2019-02-08 5.29.08.png](https://qiita-image-store.s3.amazonaws.com/0/73493/fed1f5dc-a065-04d8-537d-f8ab4a82cefd.png)

いろいろなデザインが考えられますが、今回はとりあえずこんな風にしてみます。

### App.vue

* 左側にドロワーを配置して、「ダッシュボード」「設定」「について」メニューをつけます。
* 右側にドロワーを配置して、「ログアウト」ボタンをつけます。
* 上にツールボックスを配置してドロワーの出し入れをできるようにします。

```vue

<template>
	<v-app>
		<v-navigation-drawer app clipped fixed v-model="leftDrawer" :mini-variant="leftMiniVariant">
			<v-list>
				<v-list-tile to='/'>
					<v-list-tile-action><v-icon>dashboard</v-icon></v-list-tile-action>
					<v-list-tile-content><v-list-tile-title>ダッシュボード</v-list-tile-title></v-list-tile-content>
				</v-list-tile>

				<v-list-tile to='/prefs'>
					<v-list-tile-action><v-icon>settings</v-icon></v-list-tile-action>
					<v-list-tile-content><v-list-tile-title>設定</v-list-tile-title></v-list-tile-content>
				</v-list-tile>

				<v-list-tile to='/about'>
					<v-list-tile-action><v-icon>store</v-icon></v-list-tile-action>
					<v-list-tile-content><v-list-tile-title>について</v-list-tile-title></v-list-tile-content>
				</v-list-tile>
			</v-list>
		</v-navigation-drawer>

		<v-toolbar app clipped-left clipped-right>
			<v-toolbar-side-icon @click.stop="leftDrawer = !leftDrawer"></v-toolbar-side-icon>
			<v-btn icon @click.stop="leftMiniVariant = !leftMiniVariant">
				<v-icon v-html="leftMiniVariant ? 'chevron_right' : 'chevron_left'"></v-icon>
			</v-btn>
			<v-toolbar-title>The Dashboard</v-toolbar-title>
			<v-spacer></v-spacer>
			<v-toolbar-title>{{ $store.state.user ? $store.state.user : '未ログイン' }}</v-toolbar-title>
			<v-btn icon @click.stop="rightDrawer = !rightDrawer">
				<v-icon>account_circle</v-icon>
			</v-btn>
		</v-toolbar>

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

		<v-navigation-drawer app clipped fixed v-model="rightDrawer" right>
			<v-list>
				<v-list-tile to="/login">
					<v-list-tile-action><v-icon>dashboard</v-icon></v-list-tile-action>
					<v-list-tile-content><v-list-tile-title>ログアウト</v-list-tile-title></v-list-tile-content>
				</v-list-tile>
			</v-list>
		</v-navigation-drawer>

		<v-footer fixed app><span>&copy; 2018</span></v-footer>

	</v-app>
</template>

<script>
export default {
	name: 'App'
,	data () {
		return {
			leftMiniVariant	: false
		,	leftDrawer		: false
		,	rightDrawer		: false
		}
	}
}
</script>
```

### コンポーネントたち

とりあえずダミーをおいておきます。

```views/Dashboard.vue
<template>
	<h1>Dashboard</h1>
</template>
```
```views/About.vue
<template>
	<h1>About</h1>
</template>
```
```views/Prefs.vue
<template>
	<h1>Prefs</h1>
</template>
```
```views/Login.vue
<template>
	<h1>Login/Logout</h1>
</template>
```

### Vuex(ストア)

インプリ時にきっと必要になるログイン情報をとりあえず置いておきます。

```store.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store(
	{   state       : { user    : '' }
	,   mutations   : { user    : ( state, payload ) => state.user = payload }
	}
)
```

### vue-router

```router.js
import Vue from 'vue'
import Router from 'vue-router'
import Dashboard from './views/Dashboard.vue'

Vue.use(Router)

export default new Router(
	{
		mode: 'history'
	,	base: process.env.BASE_URL
	,	routes: [
			{	path: '/'		, component: Dashboard }
		,	{	path: '/about'	, component: () => import( /* webpackChunkName: "about" */ './views/About.vue' ) }
		,	{	path: '/prefs'	, component: () => import( /* webpackChunkName: "prefs" */ './views/Prefs.vue' ) }
		,	{	path: '/login'	, component: () => import( /* webpackChunkName: "login" */ './views/Login.vue' ) }
		]
	}
)
```

### メイン

CLIが作ったままで変更ありません。

```main.js
import Vue from 'vue'
import './plugins/vuetify'
import App from './App.vue'
import router from './router'
import store from './store'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: function (h) { return h(App) }
}).$mount('#app')
```

# 最後に

[Vuetify ベースのテーマ](https://vuetifyjs.com/ja/themes/premium) がとても充実してきました。もう自分でスクラッチから作る時代ではないかもしれません。