Vue2までのOptions APIでは、this.$router
のようにthis
を介してルーターオブジェクトにアクセスをしていました。しかしながら、Composition APIのsetup
メソッド内ではthis
にアクセスすることができません。そのため、今までとは違うアプローチからアクセスする必要があります。
useRouter()・useRoute()に置き換える
ルーターオブジェクトを得るためには、vue-rouer
からuseRouter
またはuseRoute
関数をインポートします。それぞれの関数は以下のように対応しています。
Options API | Composition API |
---|---|
this.$router | useRouter |
this.$route | useRoute |
<script lang="ts">
import { defineComponent } from 'vue'
import { useRoute, useRouter } from 'vue-router'
export default defineComponent({
setup() {
const router = useRouter()
const route = useRoute()
const fetch = () => {
const { id } = route.params
store.getTodo(id)
}
const goHome = () => {
router.push('/')
}
return {
goHome,
}
},
})
</script>
useRoute()
関数から取得できるroute
オブジェクトは、リアクティブとなっています。
なお、テンプレート内では今までどおり、$router
、$route
にアクセスできます。ですから、router
または$route
オブジェクトをreturnする必要はありません。
setupメソッド外からはアクセスすることはできない
先程例示したgoHome
関数は汎用的に使えそうなのでComposition APIの流儀にならって別のファイルに分割してみたいところです。試しに、この関数をsrc/composable/router/index.ts
に配置してそこから呼び出すように変えてみましょう。
import router from '@/router'
import { useRouter } from 'vue-router'
const router = useRouter()
export const goHome = () => {
router.push('/')
}
<template>
<button @click="goHome">トップへ戻る</button>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { goHome } from '@/composables/router'
export default defineComponent({
setup() {
return {
goHome,
}
},
})
</script>
ボタンを押してみても、思いに反して反応してくれません。コンソールエラーを見てみると、どうやらuseRouter()
から得たrouter
オブジェクトがundefined
になっているようです。
コンポーネント内ナビゲーションガード
ナビゲーションガードも同様に、vue-router
から関数をインポートして使います。
Opsitions APIにおけるbeforeRouteEnter
に対応するものは提供されていないようです。
Options API | Composition API |
---|---|
beforeRouteEnter | - |
beforeRouteUpdate | onBeforeRouteLeave |
beforeRouteLeave | onBeforeRouteLeave |
<script lang="ts">
import { defineComponent } from 'vue'
import { onBeforeRouteLeave, onBeforeRouteUpdate, } from 'vue-router'
export default defineComponent({
setup() {
onBeforeRouteLeave((to, from) => {
//
})
onBeforeRouteUpdate((to, from) => {
//
})
},
})
</script>