Vuetify Vue Router まとめ

Vue RouterはLaravelの管理画面をvue-routerを使ってSPA化で使用し簡単に説明しましたがインストールや設定、リンク方法の復習からパラメータやクエリストリングの取得方法やパラメータや
クエリストリングを変更しただけの同一コンポーネントへの遷移への対応など基本的なところをVuetifyのサンプルを使って実践確認します。

開発環境

Laradock v10
Laravel 7
Vue 2.6
Vuetify 2.2

ファイル構成

resources
 ┗ js
    ┣ components
    ┃ ┣ Router1Component.vue
    ┃ ┗ Router2Component.vue
    ┣ app.js
    ┗ router.js

vue-routerのインストール&設定

インストール

# npm install vue-router

設定

require('./bootstrap');

window.Vue = require('vue');

import router from './router';
import Vuetify from 'vuetify';
import 'vuetify/dist/vuetify.min.css';
Vue.use(Vuetify);

Vue.component('example-component', require('./components/ExampleComponent.vue').default);

const app = new Vue({
    el: '#app',
    router,
    vuetify: new Vuetify()
});

Router1Component.vue、Router2Component.vueをサンプルとして使用します。

import Vue from 'vue'
import Router from 'vue-router'

import Router1 from './components/Router1Component.vue'
import Router2 from './components/Router2Component.vue'

Vue.use(Router)

export default new Router({
    mode: 'history',
    routes: [
        {
            path: '/router1',
            name: 'router1',
            component: Router1,
        },
        {
            path: '/router2/:id(\\d+)?',
            name: 'router2',
            component: Router2,
        },
    ],
})

・/router2へのアクセスはパラメータidを整数値として付加できる設定です。
・「?」を付けることでidがなくてもアクセス可能とします。

リンクの作成

/router2へのリンク作成

①直接URLを指定して

<router-link to="/router2">
  Router2
</router-link>

②pathをバインドとして

<router-link :to="{ path: '/router2' }">
  Router2
</router-link>

③nameをバインドとして

<router-link :to="{ name: '/router2' }">
  Router2
</router-link>

/router2/123?page=4 へのリンク作成

①直接URLを指定して

<router-link to="/router2/123?page=4">
  Router2
</router-link>

②pathをバインドとして

<router-link :to="{ path: '/router2/123?page=4' }">
  Router2
</router-link>

③nameをバインドとして

<router-link :to="{ name: '/router2', params:{ id: 123 }, query:{ page: 4 } }">
  Router2
</router-link>

メソッドによる遷移

this.$router.pushで可能です。

    <v-btn @click="routerPush('router2', 1234, 5)">router2/1234?page=5</v-btn>
・・・
    methods: {
      routerPush(name, id, page) {
        this.$router.push({
          name: name,
          params: {
            id: id,
          },
          query: {
            page: page,
          }
        }).catch(err => {})
      }
    }

params、QueryStringの受け取り方

/router2/123?page=4の場合

params

this.$route.params.id

QueryString

this.$route.query.page

サンプル作成

以上を踏まえてサンプルを作成してみます。

<template>
<div>

  <v-card
    max-width="344"
  >
    <v-card-title>Vue Router</v-card-title>
    <v-card-text>

      <v-list-item>
        <v-list-item-content>
          <router-link :to="{ name:'router2' }">
            router2
          </router-link>
        </v-list-item-content>
      </v-list-item>

      <v-list-item>
        <v-list-item-content>
          <router-link :to="{ name:'router2', params:{ id: 123 } }">
            router2/123
          </router-link>
        </v-list-item-content>
      </v-list-item>

      <v-list-item>
        <v-list-item-content>
          <router-link :to="{ name:'router2', params:{ id: 123 }, query:{ page: 4 } }">
            router2/123?page=4
          </router-link>
        </v-list-item-content>
      </v-list-item>

      <v-list-item>
        <v-list-item-content>
          <v-btn @click="routerPush('router2', 1234, 5)">router2/1234?page=5</v-btn>
        </v-list-item-content>
      </v-list-item>

    </v-card-text>
  </v-card>

</div>
</template>

<script>
  export default {
    data() {
      return {
      }
    },
    created() {
    },
    methods: {
      routerPush(name, id, page) {
        this.$router.push({
          name: name,
          params: {
            id: id,
          },
          query: {
            page: page,
          }
        }).catch(err => {})
      }
    }
  }
</script>
<template>
<div>

  <v-card
    max-width="344"
  >
    <v-card-title>Vue Router</v-card-title>
    <v-card-text>

      <v-simple-table>
        <template v-slot:default>
          <thead>
            <tr>
              <th class="text-left">ID</th>
              <th class="text-left">PAGE</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>{{ id }}</td>
              <td>{{ page }}</td>
            </tr>
          </tbody>
        </template>
      </v-simple-table>

      <v-card>
        <v-list>
          <v-subheader class="bg-info">同じコンポーネントへのリンク</v-subheader>
          <v-list-item-group>
            <v-list-item>
              <router-link :to="{ name:'router2', params:{ id: 12345 }, query:{ page: 6 } }">
                /router2/12345?page=6
              </router-link>
            </v-list-item>
            <v-list-item>
              <router-link :to="{ name:'router2', params:{ id: 123456 }, query:{ page: 7 } }">
                /router2/123456?page=7
              </router-link>
            </v-list-item>
          </v-list-item-group>
        </v-list>
      </v-card>

    </v-card-text>

    <v-card-actions>
      <router-link to="/router1">
        <v-btn class="mb-2">router1に戻る</v-btn>
      </router-link>
    </v-card-actions>

  </v-card>

</div>
</template>

<script>
  export default {
    data() {
      return {
        id: '',
        page: '',
      }
    },
    created() {
      const id = this.$route.params.id
      if (id) {
        this.id = id
      }
      const page = this.$route.query.page
      if (page) {
        this.page = page
      }
    },
  }
</script>
js-vue-vuetify-router-1

パラメータやクエリだけを変更したURLへの遷移は、同じコンポーネントインスタンスが再利用されるため、URLが変わってもVueインスタンスが再生成(初期化)されず、何もしない(パラメータやクエリを再取得しない)ことになりますね。

次の項目で対応しましょう。

同じコンポーネントへのリンク

$routeを監視して行先(to)のパラメータやクエリストリングを取得してそれぞれ更新するようにします。

    watch: {
      $route (to, from) {
        this.id = to.params.id
        this.page = to.query.page
      }
    },
js-vue-vuetify-router-2

OKですね!