router的全局前置守卫
router.beforeEach
每个守卫方法接收三个参数:
to: Route, 即将要进入的目标 路由对象;
from: Route,当前导航正要离开的路由;
next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。
router.beforeEach((to, form, next) => {
console.log(to, form);
next()
})
前置守卫可以用来做权限判断:
//判断用户是否登录,如果没有登录则拦截跳转,跳转到登录界面
router.beforeEach((to, form, next) => {
console.log('beforeEach', Loading);
Loading.component?.exposed?.startLoading()
let token = localStorage.getItem('token')
if (token && to.name != 'Login') {
next()
} else {
to.name == 'Login' ? next() : next('/login')
}
})
全局后置守卫
可以用来做路由跳转时 加载效果,然而和守卫不同的是,这些钩子不会接受 next
函数也不会改变导航本身
router.afterEach((to, from) => {
Loading.component?.exposed?.endLoading()
})
loading组件
nprogress:
npm install --save nprogress
引用:
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
NProgress.configure({
showSpinner: false
});
NProgress.start()
NProgress.done()
自定义loading组件:
<template>
<div class="wraps">
<div ref="bar" class="bar"></div>
</div>
</template>
<script setup lang='ts'>
import { ref, onMounted } from 'vue'
let speed = ref<number>(1)
let bar = ref<HTMLElement>()
let timer = ref<number>(0)
const startLoading = () => {
let dom = bar.value as HTMLElement;
speed.value = 1
timer.value = window.requestAnimationFrame(function fn() {
dom.style.display = 'block'
if (speed.value < 90) {
speed.value += 1;
dom.style.width = speed.value + '%'
timer.value = window.requestAnimationFrame(fn)
} else {
speed.value = 1;
window.cancelAnimationFrame(timer.value)
}
})
}
const endLoading = () => {
let dom = bar.value as HTMLElement;
setTimeout(() => {
window.requestAnimationFrame(() => {
speed.value = 100;
dom.style.width = speed.value + '%'
})
setTimeout(() => {
dom.style.display = 'none'
}, 300)
}, 500)
}
defineExpose({
startLoading,
endLoading
})
</script>
<style scoped>
.wraps {
position: fixed;
top: 0;
width: 100%;
height: 2px;
}
.bar {
height: inherit;
width: 0;
background: blue;
}
</style>
路由元信息
通过路由记录的 meta
属性可以定义路由的元信息。使用路由元信息可以在路由中附加自定义的数据,例如:
- 权限校验标识。
- 路由组件的过渡名称。
- 路由组件持久化缓存 (keep-alive) 的相关配置。
- 标题名称
const routes: Array<RouteRecordRaw> = [
{
path: "/login",
name: "Login",
component: () => import('../components/login.vue'),
meta: {
title: "登录",
transition: "animate__fadeInUp"
}
},
{
//动态路由参数
path: "/",
name: "Reg",
component: () => import('../components/reg.vue'),
alias: ['/root', '/roots', '/home'],
redirect: () => {
return {
path: "/tab1"
}
},
children: [
{
path: "/tab1",
name: "tab1",
component: () => import('../components/tab1.vue'),
meta: {
title: "测试tab1",
transition: "animate__fadeInUp"
}
},
{
path: "tab2",
name: "/tab2",
components: {
default: () => import('../components/tab2.vue'),
two: () => import('../components/login.vue')
},
meta: {
title: "测试tab222",
transition: "animate__fadeInUp"
}
}
]
}
]
使用TS扩展
如果不使用扩展 将会是unknow 类型
declare module 'vue-router' {
interface RouteMeta {
title?: string
}
}
过渡动画
transition
<router-view #default="{ route, Component }">
<transition :enter-active-class="`animate__animated ${route.meta.transition}`">
<component :is="Component"></component>
</transition>
</router-view>
上面路由过渡动画是和路由元结合的
路由滚动
使用前端路由,当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就像重新加载页面那样。vue-router 可以自定义路由切换时页面如何滚动。
当创建一个 Router 实例,你可以提供一个 scrollBehavior
方法
const router = createRouter({
history: createWebHashHistory(),
// scrollBehavior: (to, from, savePosition) => {
// console.log(to, '==============>', savePosition);
// return new Promise((r) => {
// setTimeout(() => {
// r({
// top: 100
// })
// }, 2000);
// })
// },
scrollBehavior: (to, from, savePosition) => {
console.log("滚动距离", savePosition)
if (savePosition) {
return savePosition
} else {
return {
top: 300
}
}
},
routes: routes,
});
scrollBehavior 方法接收 to 和 from 路由对象。第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
可以使用异步,也可以直接return 一个固定的高度参数
const router = createRouter({
history: createWebHistory(),
scrollBehavior: (to, from, savePosition) => {
return {
top:200
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)