Vue Routerを使う
- インストール
npm i vue-router
- vue-routerの設定を行う(ルーティングとコンポーネントの紐づけ) ( /src/router.js )
import Vue from 'vue';
import Router from 'vue-router'
import Home from '/views/Home.vue'
import About from '/views/About.vue'
Vue.use(Router) // プラグイン(どこでも使える機能)を適用するために記載
export default new Router({
routes:[
{
path:'/', // URL
component:'Home' // 上記URLのときに表示するコンポーネント
},
{
path: '/about',
component:'About'
}
]
})
- routerをVueのグロバルコンポーネントで適用する( /src/main.js )
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
new Vue({
router,
render: h => h(App)
}).$mount("app")
- 表示個所にrouter-viewを用意する (/src/App.vue)
<template>
<div>
<router-view></router-view>
</div>
</template>
さまざまな機能
URLの#を消す(mode:history)
デフォルトはmode:hash
で、#がついている。mode: history
とすることで、URLの#を消すことができる。
( /src/router.js 一部抜粋)
export default new Router({
mode: 'history',
routes:[ ... ]
})
URLを切り替える (router-link to="/")
<router-link to="リンク先">
とすることで、指定したリンク先に遷移するリンクができる (/src/App.vue)
<template>
<div>
<router-link to="/"> HOME </router-link>
<router-link to="/about"> ABOUT </router-link>
<router-view></router-view>
</div>
</template>
to
属性はv-bindでバインディングできる。
URLに応じてクラスを変える (active-class)
active-class="クラス名"
をすることでリンクを含むURLの時のみクラスが適用される。exact
をつけることで完全一致するURLの時のみ適用されるクラスを設定できる。 (/src/App.vue)
<template>
<div>
<router-link to="/" active-class="active" exact> HOME </router-link>
<router-link to="/about" active-class="active"> ABOUT </router-link>
<router-view></router-view>
</div>
</template>
<style scoped>
.active{
font-size: 30px;
}
</style>
URLをJavaScriptから変更する($router.push)
this.$router.push({path: '遷移先URL'})
とすることで、JavaScriptから遷移させることができる(/src/App.vue)
<template>
<div>
<button @click="toAbout">to About</button>
<router-view></router-view>
</div>
</template>
<script>
export default {
methods: {
toAbout() {
this.$router.push({path: 'about'})
}
}
}
</script>
動的なURL(path: /xxx/:yyy, $route.params)
path '/xxx/:yyy'
のように、コロンを使ってパラメータ(yyy
)を指定することで、動的なURLができる
(/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path:'/',
component:'Home'
},
{
path: '/about/:id', // パラメータidを指定
component:'About'
}
]
})
$route.params.idで動的なURLのパラメータにアクセスできる (/src/views/About.vue)
<template>
<div>
<!-- -->
<p>No. {{$route.params.id}}</p>
</div>
</template>
※ 動的なURLはライフサイクルフックが呼ばれないので、URLの変更で何か処理をさせたい場合は、watchで$routeを監視する。
動的なURLのパラメータをpropsからアクセス (props: true)
props: true
にすることで、動的パラメータをpropsでアクセスできる
(/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path:'/',
component:'Home'
},
{
path: '/about/:id',
component:'About',
props: true // propsを追加
}
]
})
$route.params.idで動的なURLのパラメータにアクセスできる (/src/views/About.vue)
<template>
<div>
<p>ID: {{id}}</p>
</div>
</template>
<script>
export default{
props: ['id']
}
</script>
※ 動的なURLはライフサイクルフックが呼ばれないので、URLの変更で何か処理をさせたい場合は、watchで$routeを監視する。
router-view のなかにrouter-view (children)
children
を追加することでネストされたrouter-viewを実現できる (/src/router.js)
import Vue from 'vue';
import Router from 'vue-router'
import Home from '/views/Home.vue'
import About from '/views/About.vue'
import AboutChild from '/views/AboutChild.vue'
Vue.use(Router)
export default new Router({
routes:[
{
path:'/',
component:'Home'
},
{
path: '/about',
component:'About',
children:: [ // childrenオプションでpath, componentを設定する
{path: "child", component: AboutChild} // …/about/childでアクセス可
]
}
]
})
名前付きのルートを使う (name)
name
を使ってルートに名前を設定する (/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path: '/about:id',
component:'About',
children:: [{
path: "child",
component: AboutChild,
name: 'name-child' // ルートの名前を設定
}]
}
]
})
name
で指定したルートの名前を渡す。パラメータはparams
でオブジェクトで指定する (/src/views/App.js)
<template>
<div>
<router-link :to= "{name:'name-child', params:{id:1}}"> ABOUT </router-link>
<router-view></router-view>
</div>
</template>
クエリにアクセス (query)
(/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path: '/about',
component:'About',
name: 'about' // 名前付きルートを設定
}
]
})
クリックすると/about?id=1というURLになる (/src/App.vue)
<template>
<div>
<!-- クリックすると /about?id=1&page=2というURLになる-->
<router-link :to= "{name:'about', query:{id:1, page:2}}"> ABOUT </router-link>
<!-- こちらでも可能 -->
<router-link to="/about?id=1&page=2"></router-link>
<router-view></router-view>
</div>
</template>
クエリはthis.$route.query.id
で取得できる。
リダイレクト機能 (redirect)
redirect
を使うことで、リダイレクトを実装できる (/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path: '/about',
component:'About'
},
{
path:'*', // アスタリスクを指定することで任意のURLという意味になる
redirect:'/' // 遷移先のURLを指定
}
]
})
router-viewにトランジション (transition)
router-viewにもトランジションを適用させることができる (/src/App.vue)
<template>
<div>
<transitin name="fade" mode="out-in">
<router-view></router-view>
</transitin>
</div>
</template>
<style scoped>
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active{
transition: opacity .5s
}
</style>
# idを指定する (hash)
クリックすると/about#nextというURLになる (/src/App.vue)
<template>
<div>
<!-- クリックすると /about#nextというURLになる-->
<router-link :to= "{name:'about', hash: 'next'}"> ABOUT </router-link>
<!-- こちらでも可能 -->
<router-link to="/about#next"></router-link>
<router-view></router-view>
</div>
</template>
指定IDにスクロールさせる (scrollBehavior)
トランジションがない場合のみ使用できる。これは、transitionがあると、#nextが発生する前にscrollBehaviorが起動するためである (/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path:'/',
component:'Home'
}
],
scrollBehavior(to, from, savedPosition) {
// 前回の位置に戻る
if(savedPosition) {
return savedPosition
}
// URLにhashが含んでいたらハッシュの位置まで移動
if(to.hash) {
return {
selector: to.hash
}
}
// ページの先頭に移動
return {x: 0, y: 0}
}
})
すべてのページの遷移時に実行する (beforeEach)
/src/main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
Vue.config.productionTip = false
// to:$route(次の遷移先の状態) from:$route(前の状態) next:次の遷移先に進む関数
router.beforeEach((to, from, next) => {
console.log('before each!')
// 引数も取れる
// next(false):次に遷移させない
// next('/'):'/'に遷移
next()
})
new Vue({
router,
render: h => h(App)
}).$mount("#app")
特定のページの遷移時に実行する (beforeEnter)
boforeEnter
を使う (/src/router.js 一部抜粋)
export default new Router({
routes:[
{
path: '/about',
component:'About',
beforeEnter(to, from, next) {
console.log('before enter!')
// 引数も取れる
// next(false):次に遷移させない
// next('/'):'/'に遷移
next()
}
},
]
})
ナビゲーションガードをコンポーネントに指定
Vueコンポーネントに記載する
<script>
export default {
beforeRouteEnter(to, from, next) {
// コンポーネントを描画するルートが確立する前
next()
},
beforeRouteUpdate(to, from, next) {
// コンポーネントを描画するルートが変更されたとき
next()
},
boforeRouteLeave(to, from, next) {
// コンポーネント終了後(ナビゲーションから離れていく時)
const isLeave = window.confirm("このページを離れますか?")
if(isLeave) {
next()
}else {
next(false)
}
}
}
</script>
遅延ローディング (const xx = () => import("./xxx.vue"))
router.jsのimport分の記載方法を変えることで遅延ローディング(後からjavascriptを取得する)が可能
(router.jsの一部を抜粋)
// ● 今までの書き方
// import Home from './views/Home.vue'
// ● 遅延ローディングの場合
const Home = () => import(/* webpackChunkName: "Home" */ "./views/Home.vue")
参考