Vue.js v2のrouterの基本的な使い方

Vue.js

Vue.jsのrouterの基本的な使い方をまとめました。

routerの基本的な使い方

Vue CLIでrouterをインストールすると、次のようにpackage.jsonのdependenciesに追加されます。

package.json

"vue-router": "^4.0.0-0"

main.js

import { createApp } from 'vue'
import App from './App.vue'
import router from './router' //ここはindex.jsを書かなくても自動的にindex.jsを意味する

createApp(App).use(router).mount('#app')

mains.jsには、routerのimportが確認できます。
上の文は、router/index.jsを参照していますが、index.jsを書かなくても自動的にindex.jsを意味します。

router/index.js

import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Jobs from '../views//jobs/Jobs.vue'
import JobDetails from '../views//jobs/JobDetails.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/jobs',
    name: 'Jobs',
    component: Jobs
  },
  {
    path: '/jobs/:id',//どんなidでも遷移できるようになる
    name: 'jobDetails',
    component: JobDetails,
    props: true //:idをpropsとして認めることができます
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

必要なファイルをimportして、
routesでpath、name、componentを設定します。
propsをtrueにすると、上の例のように:idとしたidをpropsとして使うことができます。

App.vue

リンクは、aタグではなく、router-linkを使います。
aタグはserverにすべての情報を取りに行きますが、router-linkならページ遷移のみなのでとても早いです。

pathプロパティとリンク

index.jsに記述されているpathプロパティとリンクさせる場合、次のように書きます。

<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
  </div>
  <!-- 下の部分がHomeならHome,AboutならAboutのrouterに変わる -->
  <router-view/>
</template>

この書き方は、index.jsに記述されているpathプロパティとリンクしているためpathが変わるたびに変更しないといけません。
よって、次のような書き方もあります。

nameプロパティとリンク

index.jsに記述されているnameプロパティとリンクさせます。

<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link :to="{name: 'About'}">About</router-link>
    <router-link :to="{name: 'Jobs'}">Jobs</router-link>
  </div>
  <!-- 下の部分がHomeならHome,AboutならAboutのrouterに変わる -->
  <router-view/>
</template>

メリットとしては、pathが変わっても大丈夫な点です。

jobs/Jobs.vue

<template>
  <h1>Jobs</h1>
    <router-link :to="{ name: 'jobDetails', params: { id: job.id } }">
      <h2>{{ job.title }}</h2>
    </router-link>
  </div>
</template>

router-linkを設定することで、それぞれのtitleのidのurlとjobDetailsのページがひもづきます。
name: 'jobDetails’でJobDetails.vueとリンクしています。
params: { id: job.id }でindex.jsのpathの:idとv-forでループしているjobのidとリンクしています。

<script>
export default {
  data() {
    return {
      jobs: [
        { title: 'UX Designer', id: 1, details: 'lorem' },
        { title: 'Web Developer', id: 2, details: 'lorem' },
        { title: 'Vue Developer', id: 3, details: 'lorem' }
      ]
    }
  }
}
</script>
<style scoped>
.job h2 {
  background-color: #f4f4f4;
  padding: 20px;
  border-radius: 10px;
  margin: 10px auto;
  max-width: 600px;
  cursor: pointer;
  color: #444;
}
.job h2:hover {
  background-color: #ddd;
}
.job a {
  text-decoration: none;
}
</style>

jobs/JobDetails.vue

index.jsでprops: trueにするとdata()ではpropsで受け取れるようになるので、
こちらでpropsにidを記述すれば使えるようになります。
propsを使わない場合は、$route.params.idとすることでアクセスすることもできます。

<template>
  <h1>Job Details Page</h1>
  <!-- index.jsに書いたidにアクセスしたい場合$route.params.idでアクセスできる -->
  <p>The job is is {{ id }}</p>
</template>
<script>
export default {
  // index.jsでprops: trueにするとdata()ではpropsで受け取れるようになる
  props: ['id'],
  // 
  // data() {
  //   return {
  //     id: this.$route.params.id
  //   }
  // }
}
</script>

redirectの設定

index.jsに以下のように記述します。

index.js

<script>
import NotFound from '../views/NotFound.vue'

const routes = [
  
  {
    ...
  },
  // redirect
  {
    path: '/current-jobs', //表示したくないリンク
    redirect: '/jobs' //redirect先のリンク
  }
]
</script>

特定のページだけをrefirectしたい場合は、その上の例のように記述します。
/current-jobsが表示したくないリンク先で、そこに遷移しようとすると、/jobsにredirectする設定です。

404ページへの遷移

routerを使うと404ページへも簡単に移動させることができます。
index.jsに追加で記述します。

index.js

<script>
import NotFound from '../views/NotFound.vue'

const routes = [
  
  {
    ...
  },
  // catchall 404
  {
    path: '/:catchAll(.*)',//ここに登録されていないすべてのpathが対象になる。一字一句この通りにすること
    name: 'NotFound',
    component: NotFound
  }
]
</script>

path: '/:catchAll(.*)’,とすることで、登録されていないすべてのpathがNotFoundのコンポーネントに移動することになります。

NotFound.vue

viewフォルダにNotFound.vueを作成して、次のように記述します。

<template>
  <h2>404</h2>
  <h3>ページが見つかりませんでした。</h3>
</template>

プログラマティックにHomeにリダイレクトする

App.vue

次のようにボタンを追加します。

<template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link :to="{name: 'About'}">About</router-link>
    <router-link :to="{name: 'Jobs'}">Jobs</router-link>
  </div>

    <button @click="redirect">Redirect</button>
    <button @click="back">Go back</button>
    <button @click="forward">Go forward</button>
  <!-- 下の部分がHomeならHome,AboutならAboutのrouterに変わる -->
  <router-view/>
</template>

ボタンには、それぞれリダイレクト用、戻る、進むのボタンになるように、v-onのclickイベントを作成します。

<script>

export default {
  methods: {
    redirect() {
      this.$router.push({name: 'Home'})//index.jsに書いたnameを記述する
    },
    back() {
      this.$router.go(-1)//go()メソッドは正負の整数を引数にとる。-1で一つ戻る、-2なら2つ戻る
    },
    forward() {
      this.$router.go(1)//先に1つ進む
    },
  }
}

</script>

$routerを使うことでそれぞれ設定することができます。
リダイレクトは、push()メソッドを使い、index.jsに書いたnameを記述します。
戻ると進むのボタンは、go()メソッドを使います。
go()メソッドは正負の整数を引数にとります。-1で一つ戻る、1なら1つ進みます。

<style scoped>
・・・
button {
  margin: 0 10px;
  padding: 10px;
  border: none;
  border-radius: 4px;
}
</style>

CSSにはbuttonのCSSを追加します。

Vue.js

Posted by devsakaso