实现
1.创建路由实例
- 使用createRouter来创建路由实例,它接受一个对象,其中包含history和routes两个属性
- history: 指定路由的历史记录模式。常见的模式有
createWebHistory
(HTML5 模式)和createWebHashHistory
(Hash 模式) - routes: 定义了一系列路由规则,每个规则包括
path
(路径)、name
(名称)和component
(组件)
import {createRouter, createWebHistory} from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/home',// 首页
name: 'Home',
component: () => import('../views/Home/Home.vue'),
},
{
path: '/detail/:id',// 详情页
name: 'Detail',
component: () => import('../views/Detail/Detail.vue')
},
{
path: '/',
redirect: '/svg'// 重定向到首页
},
{
path: '/:pathMatch(.*)*', // 匹配不到的路由,跳转到404页面
name: 'NotFound',
component: () => import('../views/404.vue')
}
]
})
2.配置路由守卫
前置守卫
- 通过跳转或取消的方式来守卫导航,在每次导航时会触发
- 注册全局前置守卫:
router.beforeEach()
- 参数:
to
,from
- 返回:
Boolean
,route
router.beforeEach(async (to, from) => {
if (
// 检查用户是否已登录, 并避免无限重定向
!isAuthenticated && to.name !== 'Login'
)
{
// 将用户重定向到登录页面
return { name: 'Login' }
}
})
解析守卫
- 类似于前置守卫,但在导航确认之前,异步路由解析之后触发
- 能够确保用户导航确认后正确获取到数据,以及避免错误执行操作
router.beforeResolve(async to => {
if (to.meta.requiresCamera) {
try {
await askForCameraPermission()//获取用户访问摄像头的权限
} catch (error) {
if (error instanceof NotAllowedError) {
// ... 处理错误,然后取消导航
return false
} else {
// 意料之外的错误,取消导航并把错误传给全局处理器
throw error
}
}
}
})
组件内守卫
- 在组件内部注册路由守卫,只对该组件生效
beforeRouteEnter(to, from) {
// 在渲染该组件的对应路由被验证前调用
// 不能获取组件实例 `this` !
// 因为当守卫执行时,组件实例还没被创建!
},
beforeRouteUpdate(to, from) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 `/users/:id`,在 `/users/1` 和 `/users/2` 之间跳转的时候,
// 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
},
beforeRouteLeave(to, from) {
// 在导航离开渲染该组件的对应路由时调用
// 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
},
3.导出路由
- 将创建的路由器实例
router
导出,以便在应用的其他部分使用。
export default router
4.使用路由
获取路由信息
- useRoute(): 返回当前路由信息
- useRouter(): 返回路由器实例
//导航完成后获取数据, 在数据获取期间显示“加载中”的指示
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { getPost } from './api.js'
const route = useRoute()
const loading = ref(false)
const post = ref(null)
const error = ref(null)
// 侦听路由的参数,以便再次获取数据
watch(() => route.params.id, fetchData, { immediate: true })
async function fetchData(id) {//这里的id是响应式数据源route.params.id的变化后的新值
error.value = post.value = null
loading.value = true
try {
// 用获取数据的工具函数 / API 包裹器替换 `getPost`
post.value = await getPost(id)
} catch (err) {
error.value = err.toString()
} finally {
loading.value = false
}
}
进行路由导航
- router.push(): 导航到不同的位置, 会在历史堆栈内留下足迹
- router.replace(): 替换当前路由位置,因此不会记录到历史堆内
- router.go(): 在历史堆栈中前进或后退多少步
router.push({ path: `/user/${username}` }) // -> /user/eduardo
// 如果可能的话,使用 `name` 和 `params` 从自动 URL 编码中获益
router.push({ name: 'user', params: { username } }) // -> /user/eduardo
// `params` 不能与 `path` 一起使用
router.push({ path: '/user', params: { username } }) // -> /user
router.push({ path: '/home', replace: true })
router.replace({ path: '/home' })
router.go(3)
Last updated on