1. nobu-maple

    No comment

    nobu-maple
Changes in title
-Laravel5.6 + Vue2.5 でvue-routerとVuetifyを使ってみる
+Laravel5.7 + Vue2.5 でvue-routerとVuetifyを使ってみる
Changes in body
Source | HTML | Preview
@@ -1,489 +1,672 @@
+※ 2018/10/17 Laravel5.6 から 5.7 に記述を更新
+
Laravel でユーザ認証した後、Vue側でRouter使ってページを切り替えてみる
ユーザ管理(社員管理)のページとしてデータテーブルを使えるように Vuetify も使ったページを作成する
-環境設定他これまでの記事はこちら
-[Qiita: Laravel5.6 + Vue2.5 でLaravelからVueにデータを渡す](https://qiita.com/nobu-maple/items/a704fe70809b0394b5c9)
-[Qiita: Laravel5.6 + Vue2.5 でLaravel ユーザでログインして Vue画面を表示する](https://qiita.com/nobu-maple/items/f0ee9324eacfed6eddd7)
-[Qiita: Laravel5.6 + Vue2.5 でユーザ権限によってvueコンポーネントを出しわける](https://qiita.com/nobu-maple/items/3eb735c148a698585fa3)
+環境設定他関連記事はこちら
+[Laravel + Vue + Vuetify で業務サイト作ってみる](https://qiita.com/nobu-maple/items/d1e7170d62ab07890a7a)
-#1.各パッケージをインストール
+#1.各パッケージをインストール
-npm でサクッと
-今後のために日付処理系の [moment.js](https://momentjs.com/) も入れておく
+npm でサクッと vue-router と vuetify を入れとく
+vuetify は[こちら](https://vuetifyjs.com/ja/getting-started/quick-start)を参考に
```bash
npm install vue-router
npm install vuetify
npm install css-loader
npm install material-design-icons-iconfont
-npm install moment
```
インストール後はこんな感じ
```json:package.json
{
"private": true,
"scripts": {
"dev": "npm run development",
"development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "npm run development -- --watch",
"watch-poll": "npm run watch -- --watch-poll",
"hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"devDependencies": {
"axios": "^0.18",
- "bootstrap": "^4.1.2",
- "cross-env": "^5.2.0",
+ "bootstrap": "^4.0.0",
+ "cross-env": "^5.1",
"jquery": "^3.2",
"laravel-mix": "^2.0",
- "lodash": "^4.17.4",
+ "lodash": "^4.17.5",
"popper.js": "^1.12",
"vue": "^2.5.7"
},
"dependencies": {
"css-loader": "^1.0.0",
"material-design-icons-iconfont": "^3.0.3",
- "moment": "^2.22.2",
"vue-router": "^3.0.1",
- "vuetify": "^1.1.5"
+ "vuetify": "^1.2.9"
}
}
```
-#2.読み込み設定
+#2.読み込み設定
-追加したパッケージを読み込むように設定
+追加した Vuetify と router を読み込むように設定
+router については外出しして管理しやすいようにしとく
+Vuetify は[色設定](https://vuetifyjs.com/ja/style/theme)も入れておく
+
-```javascript:resources/assets/js/app.js
- /**
- * First we will load all of this project's JavaScript dependencies which
- * includes Vue and other libraries. It is a great starting point when
- * building robust, powerful web applications using Vue and Laravel.
- */
- require('./bootstrap');
+```javascript:resources/js/app.js
+require('./bootstrap');
- window.Vue = require('vue');
-★1 window.Vuetify = require('vuetify');
-★1 Vue.use(Vuetify);
+// Vue
+import Vue from 'vue'
-★2 import 'vuetify/dist/vuetify.min.css';
-★2 import 'material-design-icons-iconfont/dist/material-design-icons.css';
+// Vuetify
+import Vuetify from 'vuetify'
+import colors from 'vuetify/es5/util/colors'
-★3 import VueRouter from 'vue-router';
-★3 Vue.use(VueRouter);
+Vue.use(Vuetify, {
+ theme: {
+ primary: colors.indigo.base,
+ secondary: colors.blue.base,
+ accent: colors.amber.base,
+ }
+});
+import 'vuetify/dist/vuetify.min.css'
+import 'material-design-icons-iconfont/dist/material-design-icons.css'
- Vue.component('example-component', require('./components/ExampleComponent.vue'));
- Vue.component('admin-component', require('./components/AdminComponent.vue'));
-★4 const router = new VueRouter({
-★4 mode: 'history',
-★4 routes: [
-★4 { path: '/', component: require('./components/DashboardComponent.vue')},
-★4 { path: '/admin/user', component: require('./components/Admin/UserComponent.vue' )},
-★4 ]
-★4 });
+// Vue-Router
+import router from './router'
+// Main app
+const app = new Vue({
+ el: '#app',
+ router,
+});
+```
- /**
- * Next, we will create a fresh Vue application instance and attach it to
- * the page. Then, you may begin adding components to this application
- * or customize the JavaScript scaffolding to fit your unique needs.
- */
+## router 用設定
- const app = new Vue({
- el: '#app',
-★4 router,
- });
+app.js と同じ階層に router ディレクトリを掘っておく
+
+```bash
+$ mkdir resources/js/router
```
-★1 Vuetify 読み込み設定
-★2 Vuetify 関連のCSS読み込み設定
-★3 router 読み込み設定
-★4 router ルーティング設定
+作った ディレクトリに router 用設定ファイルを作成
+```javascript:resources/js/router/index.js
+
+import Vue from 'vue'
+import Router from 'vue-router'
+Vue.use(Router)
+
+//
+import example_component from '../components/ExampleComponent.vue'
+import admin_component from '../components/AdminComponent.vue'
+import r_link from '../components/RouterLink.vue'
+
+//
+Vue.component('example-component', example_component)
+Vue.component('admin-component', admin_component)
+Vue.component('r-link', r_link)
+
+//
+import home from '../components/HomeComponent.vue'
+import admin_user from '../components/Admin/UserComponent.vue'
+
+export default new Router({
+ mode: 'history',
+ routes: [
+ { path: '/', name: 'home', component: home, meta: {name: 'ホーム', icon: 'home'}},
+ { path: '/admin/user', name: 'admin_user', component: admin_user, meta: {name: '社員管理', icon: 'supervisor_account'}},
+ ],
+})
+```
-#3.routerで切り替えるベースコンポーネント作成
+リンク用の文字とかアイコンをここに定義
+各画面で表示する文字とかアイコンはこの定義を参照することで変更も1か所で済むようにしておく
+
+
+
+
+#3.routerで切り替えるベースコンポーネント作成
vue-routerで切り替えるページのベースとなるコンポーネントを作成する
レイアウトは Vuetify のテンプレートを利用させてもらう
-```html:resources/assets/js/components/AdminComponent.vue
+```html:resources/js/components/AdminComponent.vue
<template>
<v-app id="app">
<v-navigation-drawer v-model="drawer" clipped fixed app >
<v-list dense>
- <router-link to="/home">
- <v-list-tile @click="drawer = !drawer">
- <v-list-tile-action> <v-icon>home</v-icon> </v-list-tile-action>
- <v-list-tile-content>
- <v-list-tile-title>HOME</v-list-tile-title>
- </v-list-tile-content>
- </v-list-tile>
- </router-link>
-
- <router-link to="/admin/user">
- <v-list-tile @click="drawer = !drawer">
- <v-list-tile-action> <v-icon>supervisor_account</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>
- </router-link>
+ <r-link linkname='home'></r-link>
+ <r-link linkname='admin_user'></r-link>
</v-list>
</v-navigation-drawer>
- <v-toolbar color="indigo" dark fixed app clipped-left>
+ <v-toolbar color="primary" dark fixed app clipped-left>
<v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
- <v-toolbar-title>Application</v-toolbar-title>
+ <v-toolbar-title>{{title}}</v-toolbar-title>
<v-spacer></v-spacer>
{{ name }}
<v-btn icon @click="axiosLogout()">
<v-tooltip left>
<v-icon slot="activator" color="white" dark >exit_to_app</v-icon>
<span>ログアウト</span>
</v-tooltip>
</v-btn>
</v-toolbar>
- <v-fade-transition mode="out-in">
- <router-view></router-view>
- </v-fade-transition>
-
- <v-footer color="indigo" dark app fixed>
- <span class="white--text ml-3">
- &copy; 2018
- <a class="white--text" href="https://qiita.com/nobu-maple">Qiita nobu-maple</a>
- </span>
+ <v-content>
+ <v-container fluid fill-height
+ <v-layout justify-center fluid column>
+ <v-fade-transition mode="out-in">
+ <router-view @axios-logout="axiosLogout"></router-view>
+ </v-fade-transition>
+ </v-layout>
+ </v-container>
+ </v-content>
+
+ <v-footer color="primary" dark app fixed>
+ <span class="white--text ml-3" v-html="footer"></span>
</v-footer>
</v-app>
</template>
<script>
export default {
- data: () => ({
- drawer: false,
- }),
+ name: 'AdminComponent',
props: {
- id: String,
name: String,
- role: String,
logout: String,
},
+ data: () => ({
+ drawer: false,
+ footer: 'foo-----footer',
+ title: 'tit------title',
+ }),
+
mounted() {
- console.log('Component mounted.')
+ console.log('AdminComponent mounted.')
+
+ if (process.env.MIX_FOOTER) { this.footer = process.env.MIX_FOOTER }
+ if (process.env.MIX_TITLE) { this.title = process.env.MIX_TITLE }
+
},
methods: {
axiosLogout: function() {
- var params = new URLSearchParams()
- axios.post(this.logout, params, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
-
-
+ axios.post(this.logout)
+
.then( function (response) {
console.log(response)
}.bind(this))
.catch(function (error) {
- if (error.response.status === 401) {
- var parser = new URL(this.logout)
- location.href=parser.origin
+ console.log(error)
+ if (error.response) {
+ if (error.response.status) {
+ if (error.response.status == 401 || error.response.status == 419) {
+ var parser = new URL(this.logout)
+ location.href=parser.origin
+ }
+ }
+
}
- console.log(error.response)
}.bind(this))
},
+ },
+ }
+</script>
+```
+
+
+## リンク部分をコンポーネント化
+リンク毎に同じ定義を書くのもめんどくさいのでコンポーネントにして、アイコンやらタイトルやらは route/index.js の定義から設定できるようにしとく
+
+
+```html:resources/js/components/RouterLink.vue
+<template>
+ <router-link :to="{name: linkname}">
+ <v-list-tile>
+ <v-list-tile-action>
+ <v-icon>{{ getRoute( linkname, 'icon' ) }}</v-icon>
+ </v-list-tile-action>
+ <v-list-tile-content>
+ <v-list-tile-title>{{getRoute( linkname, 'name' )}}</v-list-tile-title>
+ </v-list-tile-content>
+ </v-list-tile>
+ </router-link>
+</template>
+
+<script>
+ export default {
+ name: 'routerlink',
+ props: {
+ linkname: String,
+ },
+
+ methods: {
+ getRoute(name, key) {
+ for(var i=0 ; i<this.$router.options.routes.length; i++) {
+ if (this.$router.options.routes[i].name == name ) {
+ return this.$router.options.routes[i].meta[key]
+ }
+ }
+ },
},
+
}
</script>
+
+<style>
+ a:hover {
+ text-decoration: none;
+ }
+</style>
```
-#4.home コンポーネント作成
+
+
+#4.home コンポーネント作成
とりあえず空のコンポーネント
Vuetifyで書いておく
-```html:resources/assets/js/components/HomeComponent.vue
+```html:resources/js/components/HomeComponent.vue
<template>
<v-content>
<v-container fluid fill-height>
<v-layout justify-center fluid>
<v-flex xs12 offset-mx5>
Home Component.
</v-flex>
</v-layout>
</v-container>
</v-content>
</template>
<script>
export default {
data: () => ({
}),
props: {
},
created() {
- console.log('Component created.')
+ console.log('Home Component created.')
this.initialize()
},
mounted() {
- console.log('Component mounted.')
+ console.log('Home Component mounted.')
},
methods: {
initialize: function() {
},
},
}
</script>
```
-#5.ユーザ一覧を表示するコンポーネントを作成
+#5.ユーザ一覧を表示するコンポーネントを作成
-Vuetify の[データテーブル](https://vuetifyjs.com/ja/components/data-tables)を利用します
-ユーザ一覧は axios で取ってきてテーブルにデータをセット
+Vuetify の[データテーブル](https://vuetifyjs.com/ja/components/data-tables)を利用して登録済みのユーザ(社員)情報を一覧表示してみます
+
+ユーザ情報は axios で取ってきてデータテーブルにセット
検索とページングとソートの設定もしときます
-```html:resources/assets/js/components/Admin/UserComponent.vue
-<template>
- <v-content>
- <v-container fluid fill-height>
- <v-layout justify-center fluid>
- <v-flex xs12 offset-mx5>
- <v-card xs12>
+データテーブル構造は動的に headers に設定しているやつをセットするようにしてます
+ついでに連番も表示するようにしておきました
- <v-card-title class="title">
- <v-icon class="ml-2">supervisor_account</v-icon> 社員管理
- <v-spacer></v-spacer>
- <v-text-field
- v-model="search"
- append-icon="search"
- label="Search"
- single-line
- hide-details
- ></v-text-field>
- </v-card-title>
-
- <v-data-table
- :headers="headers"
- :items="users"
- :pagination.sync="pagination"
- :rows-per-page-items='[10,25,50,{"text":"All","value":-1}]'
- :loading="loading"
- :search="search"
- class="elevation-0"
- >
-
- <v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
- <template slot="items" slot-scope="props">
- <tr @click="props.expanded = !props.expanded">
- <td class="text-xs-center" xs1>{{ (props.index + 1) + (pagination.page - 1) * pagination.rowsPerPage }}</td>
- <td class="text-xs-left">{{ props.item.loginid }}</td>
- <td class="text-xs-left">{{ props.item.name }}</td>
- <td class="text-xs-left">{{ props.item.role }} - {{ props.item.role == '10' ? 'ユーザ' : '管理者' }}</td>
- </tr>
- </template>
- </v-data-table>
+```html:resources/js/components/Admin/UserComponent.vue
+<template>
+ <v-flex>
+ <v-card xs12 class="m-3 px-3">
- </v-card>
- </v-flex>
- </v-layout>
- </v-container>
- </v-content>
+ <v-card-title class="title">
+ <v-icon class="pr-2">{{ $route.meta.icon }}</v-icon> {{ $route.meta.name }} {{ /* 社員管理 */ }}
+ <v-spacer></v-spacer>
+ <v-spacer></v-spacer>
+ <v-text-field
+ v-model="search"
+ append-icon="search"
+ label="Search"
+ single-line
+ hide-details
+ ></v-text-field>
+ </v-card-title>
+
+ <v-data-table
+ :headers="headers"
+ :items="tabledata"
+ :pagination.sync="pagination"
+ :rows-per-page-items='[10,25,50,{"text":"All","value":-1}]'
+ :loading="loading"
+ :search="search"
+ class="elevation-0 p-1"
+ >
+ <v-progress-linear slot="progress" color="blue" indeterminate></v-progress-linear>
+
+ <template slot="items" slot-scope="props">
+ <tr>
+ <td class="text-xs-center" xs1>{{ (props.index + 1) + (pagination.page - 1) * pagination.rowsPerPage }}</td>
+ <template v-for="n in (headers.length - 1)">
+ <td :class="'text-xs-' + headers[n].align" style="white-space: nowrap;" v-text="props.item[headers[n].value]"></td>
+ </template>
+ </tr>
+ </template>
+
+ </v-data-table>
+ </v-card>
+ </v-flex>
</template>
<script>
export default {
+ name: 'UserComponent',
+
+ props: {
+ logout: String,
+ },
+
data: () => ({
loading: true,
search: '',
- pagination: { sortBy: 'name', descending: true, },
+ pagination: { sortBy: 'name', descending: false, },
- users: [],
+ tabledata: [],
headers: [
{ align: 'center', sortable: false, text: 'No', },
{ align: 'left', sortable: true, text: '社員ID', value: 'loginid' },
{ align: 'left', sortable: true, text: '氏名', value: 'name' },
- { align: 'left', sortable: true, text: '権限', value: 'role' },
+ { align: 'center', sortable: true, text: '権限', value: 'role' },
],
}),
- props: {
- },
-
created() {
- console.log('Component created.')
+ console.log('User Component created.')
this.initialize()
},
- mounted() {
- console.log('Component mounted.')
- },
-
methods: {
initialize: function() {
this.getUsers()
},
- getUsers: function() {
- var params = new URLSearchParams()
-
+ getUsers() {
this.loading = true
- axios.post('/api/admin/user/', params, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
+ axios.post('/api/admin/user')
.then( function (response) {
this.loading = false
- console.log(response)
- this.users = response.data.users
+console.log(response)
+ if (response.data.users) {
+ this.tabledata = response.data.users
+ this.setRole()
+ }
+
}.bind(this))
.catch(function (error) {
this.loading = false
- console.log(error.response)
-
+ console.log(error)
+ if (error.response) {
+ if (error.response.status) {
+ if (error.response.status == 401 || error.response.status == 419) {
+ this.$emit('axios-logout')
+ }
+ }
+ }
+
}.bind(this))
},
+ setRole() {
+ for (var i=0; i<this.tabledata.length; i++) {
+ if (this.tabledata[i].role) {
+ if (this.tabledata[i].role == 5) { this.tabledata[i].role = '管理者' }
+ if (this.tabledata[i].role == 10) { this.tabledata[i].role = 'ユーザ' }
+ }
+ }
+ },
},
}
</script>
```
+権限(role)は数字で出されてもわかりにくいので日本語に変換(setRole)して表示するようにしています
+
-#6.ユーザ用コントローラを作成
+
+#6.ユーザ用コントローラを作成
ひな形をまず作って
```bash
php artisan make:controller UserController
```
一覧のデータとして全件を返す index を定義しときます
```php:app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
-use App\User;
+use App/User;
class UserController extends Controller
{
- public function index()
- {
- $users = User::all();
- return ['users' => $users];
- }
+ public function index()
+ {
+ $users = User::all();
+ return ['users' => $users];
+ }
+}
+```
+
+## 権限(role)も表示対象にする
+
+App/User.php でroleは隠す設定にしていたので、hiddenからfillableに変更
+
+```php:app/User.php
+<?php
+
+namespace App;
+
+use Illuminate\Notifications\Notifiable;
+use Illuminate\Contracts\Auth\MustVerifyEmail;
+use Illuminate\Foundation\Auth\User as Authenticatable;
+
+class User extends Authenticatable
+{
+ use Notifiable;
+
+ /**
+ * The attributes that are mass assignable.
+ *
+ * @var array
+ */
+ protected $fillable = [
+ 'name',
+// 'email',
+ 'loginid',
+ 'password',
+ 'role',
+ ];
+
+ /**
+ * The attributes that should be hidden for arrays.
+ *
+ * @var array
+ */
+ protected $hidden = [
+ 'password',
+ 'remember_token',
+ ];
}
```
-#7.Laravel側のルーティング設定
+
+#7.Laravel側のルーティング設定
管理者以外はアクセスできないように定義したGATEで制限もかけときます
```php:routes/web.php
<?php
-/*
-|--------------------------------------------------------------------------
-| Web Routes
-|--------------------------------------------------------------------------
-|
-| Here is where you can register web routes for your application. These
-| routes are loaded by the RouteServiceProvider within a group which
-| contains the "web" middleware group. Now create something great!
-|
-*/
-
Route::get('/', function () {
return view('home');
})->middleware('auth');
-//Auth::routes();
-
// Authentication Routes...
-Route::get('login', 'Auth\LoginController@showLoginForm')->name('login');
-Route::post('login', 'Auth\LoginController@login');
-Route::post('logout', 'Auth\LoginController@logout')->name('logout');
+Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
+Route::post('/login', 'Auth\LoginController@login');
+Route::post('/logout', 'Auth\LoginController@logout')->name('logout');
-Route::get('/home', 'HomeController@index')->name('home');
+// Admin
+Route::group( ['middleware' => ['auth', 'can:admin']], function() {
-Route::group(['middleware' => ['auth', 'can:admin-higher']], function () {
+ // USER
Route::post('/api/admin/user', 'UserController@index')->name('admin/user');
});
+// Other
Route::get('/{any}', function () {
- Route::auth();
- return view('home');
-})->where('any', '.*');
+ return view('home');
+})->middleware('auth')->where('any', '.*');
+
+
```
-#8.動作確認
+#8.動作確認
コンパイルして、サーバを起動して
```bash
npm run dev
php artisan serve --host=172.16.0.100 --port=8000
```
ブラウザでアクセスして
http://172.16.0.100:8000/
↓↓
ログインページへ飛ばされて
http://172.16.0.100:8000/login
-![login.png](https://qiita-image-store.s3.amazonaws.com/0/153259/8d0ccfbc-d759-ce7e-7838-578453181406.png)
↓↓
User の権限でログインしたら今までの Vue コンポーネントが表示されて
-![user.png](https://qiita-image-store.s3.amazonaws.com/0/153259/06e6a83d-b865-ea2b-4c23-f37e8f42cc35.png)
+![172.16.0.100_8000_js_colors.js.map.png](https://qiita-image-store.s3.amazonaws.com/0/153259/5efb3449-3cd5-654a-717c-f0414945f979.png)
↓↓
ログアウトして 今度は Admin の管理者権限でログインしたら
-![login_admin.png](https://qiita-image-store.s3.amazonaws.com/0/153259/0d79e024-8fa2-6334-3717-b6fddc50644c.png)
↓↓
Vuetify で作った Adminコンポーネントが表示されて
-![admin_top.png](https://qiita-image-store.s3.amazonaws.com/0/153259/f97b2f83-3672-935b-7ba2-3ffba0691d30.png)
+![172.16.0.100_8000_js_colors.js.map.png](https://qiita-image-store.s3.amazonaws.com/0/153259/01b0fef8-34b4-f004-97b8-34adf116f3fa.png)
↓↓
メニューから 「社員管理」を選ぶと vue-router の機能で一覧のコンポーネントに切り替わり
+![172.16.0.100_8000_js_colors.js.map.png](https://qiita-image-store.s3.amazonaws.com/0/153259/da61591e-b254-0e7a-c91e-1493eced5aee.png)
-![admin_menu.png](https://qiita-image-store.s3.amazonaws.com/0/153259/f8efdea8-0036-74a9-b4e4-a9fdf36081bc.png)
↓↓
User情報を axios が取ってきて Vuetify のデータテーブルにセットして表示
+![172.16.0.100_8000_js_colors.js.map.png](https://qiita-image-store.s3.amazonaws.com/0/153259/325a2bac-4548-0e3d-3370-6d75f52d2c68.png)
-![admin_userlist.png](https://qiita-image-store.s3.amazonaws.com/0/153259/e513867d-0315-55fa-cda3-1353d6fbe7e6.png)
検索とかページングとかソートとかの動作もうまく動いているようです
+![172.16.0.100_8000_js_colors.js.map.png](https://qiita-image-store.s3.amazonaws.com/0/153259/2d60f8f7-ba7a-f4ba-ad7a-5d4ad6b5e72c.png)
+
+
+# ヘッダーとフッターの環境設定
+
+ヘッダーとフッターを環境変数から取得するようにしてあるので
+
+```html:resources/js/components/AdminComponent.vue
+~~
+ mounted() {
+ console.log('AdminComponent mounted.')
+
+ if (process.env.MIX_FOOTER) { this.footer = process.env.MIX_FOOTER }
+ if (process.env.MIX_TITLE) { this.title = process.env.MIX_TITLE }
+ },
+~~
+```
+
+環境変数を設定
+
+```javascript:.env
+~~
+
+MIX_FOOTER="フッター文字列を指定"
+MIX_TITLE="タイトル指定"
+```
+
+末尾に定義を追加
+
+###ついでにVuetifyの色設定も変更してみる
+
+```javascript:resources/js/app.js
+~~~
+Vue.use(Vuetify, {
+ theme: {
+ primary: colors.amber.base,
+~~~
+```
+
+indigo 指定を amber 指定に変更
+
+
+###コンパイルして再表示
+
+
+```bash
+npm run dev
+php artisan serve --host=172.16.0.100 --port=8000
+```
+
+色とタイトルとフッターが変わったよ
+![172.16.0.100_8000_admin_user.png](https://qiita-image-store.s3.amazonaws.com/0/153259/74f3cb9d-26f2-9663-edc5-63d48ad5c982.png)
+
+
+
+以上
+Vue-Router でページを切り替えて
+Vuetify でデータテーブルを表示できました
+
+ソースはこちら
+https://github.com/u9m31/u9m31/tree/step04
+
+
+
+