Vue.js v2のrouterの基本的な使い方
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を追加します。