完善路由功能路由
大纲链接 §
[toc]
动态路由'/edit/:blogId'
- 在请求URL 为
'/edit/:blogId'
、'/detail/:blogId'
、'/user/:userId'
、时需要额外传入动态URL信息 '/detail/:blogId'
博客详情,需要blogId
信息'/edit/:blogId'
博客编辑,需要blogId
信息'/user/:userId'
博客编辑,需要userId
信息- 其他比如创建
'/create'
就无需:blogId
添加路由元信息
如何将任意信息附加到路由上,例如:过渡名称、谁可以访问路由等
meta
字段可以用来附加 是否需要访问权限,使得只有经过身份验证的用户才能访问该路由- 否则就重定向到登录页面
/login
- 并且在地址栏中增加重定向信息
/login?redirect=/myblog
,登录后URL仍可以定向到之前希望访问的页面
- 否则就重定向到登录页面
- 在路由列表
routes
中需要身份认证的路由对象上,添加meta
字段来实现:- 在路由配置中添加
meta
字段 meta: { requiresAuth: true },
- 在路由全局前置守卫中设置判断条件
- 访问需要身份认证的 URL
to.matched.some(record => (record.meta.requiresAuth))
- 查找配置列表中
meta
字段的requiresAuth
属性
- 在路由配置中添加
- 可以在路由地址和导航守卫上都被访问到,配合导航守卫钩子,处理身份认证的逻辑
@/router/index.ts
|
|
to.matched.some(record => { return record.meta.requiresAuth; })
遍历匹配, 每一个需要身份认证的 URL- Array.prototype.some() MDN
arr.some(callback(element[, index[, array]])[, thisArg]): boolean
- 编程式导航
router.push('/users/posva#bio')
- 标准化的路由地址
- 匹配的组件可以从
router.currentRoute.value.matched
中获取
路由重定向
处于未登录状态时,访问需要身份验证(
meta: {requiresAuth: true},
)的URL
,如何设置 登录后重定向回该URL
- 在全局路由守卫中设置回调
- 取得
store
中存储的登录信息(使用pinia
作为状态管理库代替vuex
)
|
|
举例:
- 在登录组件
Login.tsx
的onLogin
方法中- 获取当前页面URL的重定向属性值
router.currentRoute.value.query.redirect
router
由const router = useRouter();
定义- 调用接口的方法
authStore.login(logString).then()
return router.push({path: (router.currentRoute.value.query.redirect as string) || '/' /* 首页保底 */});
- 成功,跳转重定向页面 或者 首页 作为保底
- 获取当前页面URL的重定向属性值
- 回顾在路由全局前置钩子中设置:
- 判断是需要登录,即匹配路由元信息
- 访问需要身份认证的 URL
to.matched.some(record => (record.meta.requiresAuth))
\- 判断
store
中 的登录状态const {getIsLogin,} = storeToRefs(useAuthStore());
- 未登录
!getIsLogin.value
- 执行重定向到登录页面:
next({ path: '/login', query: {redirect: to.fullPath} });
- 保留原重定向路径
query: {redirect: to.fullPath}
,设置到/login
后
- 执行重定向到登录页面:
- 已登录,直接
next()
- 判断
- 访问无需身份认证的 URL
- 直接
next()
- 直接
- 组件中使用
router.currentRoute.value.query.redirect
获取查询参数中的重定向字段
路由重定向的bug
处于已登录状态时,在编辑博客页面刷新,仍会跳转至登录页面
- 原因是的全局路由钩子中没有向服务器验证当前登录状态
store.checkLogin()
- 全局路由钩子中直接获取
store
中的登录状态的时机出错,此时BlogHeader
刚发出请求,还未更新store
中的登录状态信息 - 而是直接使用了
store
中的登录状态来判断,即store.getIsLogin
- 依据当前登录状态来判断是否需要重定向到登录页面
Login.tsx
|
|
异步加载 ⇧
@/router/index.ts
|
|
- 打包时会分成不同的
.js
文件
权限验证 ⇧
- 使用
JWT
来进行身份验证 - 相关
API
接口 - 使用的组件
权限控制 ⇧
- 使用的 路由钩子
- 相关
API
接口 - 使用的组件
完整
@/router/index.ts
|
|
其他处理
处理导航结果
- 导航是异步的,需要 await router.push 返回的 promise
|
|
- 通过导航结果来执行后续逻辑
- 检测导航故障
- 导航故障的属性
- 检测重定向
路由懒加载
打包构建应用时,JavaScript 包会变得非常大,影响页面加载
- 如果我们能把不同路由对应的组件分割成不同的代码块
- 当路由被访问的时候才加载对应组件,这样就更高效
createRouter
中的component
选项 (和 components) 配置接收一个返回 Promise 组件的函数,Vue Router 只会在第一次进入页面时才会获取这个函数,然后使用缓存数据- 如果使用的是 webpack vite 之类的打包器,它将自动从代码分割中受益
注意 不要在路由中使用异步组件
- 异步组件仍然可以在路由组件中使用,但路由组件本身就是动态导入的
过渡动效
滚动行为处理
自定义封装一个方法
@/utils/scrollToTop.ts
|
|
window.requestAnimationFrame()
告诉浏览器希望执行一个动画- 并且要求浏览器在下次重绘之前调用指定的回调函数更新动画
- 该方法需要传入一个回调函数作为参数,该回调函数会在浏览器下一次重绘之前执行
requestAnimationFrame
:优势:由系统决定回调函数的执行时机60Hz
的刷新频率,那么每次刷新的间隔中会执行一次回调函数,不会引起丢帧,不会卡顿
参考文章
相关文章
- 无
- 作者: Joel
- 文章链接:
- 版权声明
- 非自由转载-非商用-非衍生-保持署名