Vue 路由器和组合 API
Vue 的 组合 API 的引入开辟了新的可能性,但为了能够充分发挥 Vue 路由器的潜力,我们需要使用一些新函数来替换对 this
的访问以及组件内导航守卫。
在 setup
中访问路由器和当前路由
因为我们在 setup
中无法访问 this
,所以我们不能直接访问 this.$router
或 this.$route
。相反,我们使用 useRouter
和 useRoute
组合函数
vue
<script setup>
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
function pushWithQuery(query) {
router.push({
name: 'search',
query: {
...route.query,
...query,
},
})
}
</script>
route
对象是一个响应式对象。在大多数情况下,你应该避免观察整个 route
对象。相反,你可以直接观察你期望改变的属性
vue
<script setup>
import { useRoute } from 'vue-router'
import { ref, watch } from 'vue'
const route = useRoute()
const userData = ref()
// fetch the user information when params change
watch(
() => route.params.id,
async newId => {
userData.value = await fetchUser(newId)
}
)
</script>
请注意,我们仍然可以在模板中访问 $router
和 $route
,因此如果我们只需要在模板中使用这些对象,则无需使用 useRouter
或 useRoute
。
导航守卫
Vue 路由器将更新和离开守卫公开为组合 API 函数
vue
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'
import { ref } from 'vue'
// same as beforeRouteLeave option but with no access to `this`
onBeforeRouteLeave((to, from) => {
const answer = window.confirm(
'Do you really want to leave? you have unsaved changes!'
)
// cancel the navigation and stay on the same page
if (!answer) return false
})
const userData = ref()
// same as beforeRouteUpdate option but with no access to `this`
onBeforeRouteUpdate(async (to, from) => {
// only fetch the user if the id changed as maybe only the query or the hash changed
if (to.params.id !== from.params.id) {
userData.value = await fetchUser(to.params.id)
}
})
</script>
组合 API 守卫也可以在 <router-view>
渲染的任何组件中使用,它们不必像组件内守卫那样直接用于路由组件。
useLink
Vue 路由器将 RouterLink 的内部行为公开为一个组合函数。它接受一个响应式对象,例如 RouterLink
的道具,并公开低级属性以构建你自己的 RouterLink
组件或生成自定义链接
vue
<script setup>
import { RouterLink, useLink } from 'vue-router'
import { computed } from 'vue'
const props = defineProps({
// add @ts-ignore if using TypeScript
...RouterLink.props,
inactiveClass: String,
})
const {
// the resolved route object
route,
// the href to use in a link
href,
// boolean ref indicating if the link is active
isActive,
// boolean ref indicating if the link is exactly active
isExactActive,
// function to navigate to the link
navigate
} = useLink(props)
const isExternalLink = computed(
() => typeof props.to === 'string' && props.to.startsWith('http')
)
</script>
请注意,RouterLink 的 v-slot
提供与 useLink
组合函数相同的属性。