vue3中vue-router详解
https://juejin.cn/post/7143890189524402183
安装
shell
npm install vue-router@4
新建router.js文件
src/router/router.js
js
const routes = [
{
path: '/',
redirect: '/login',
},
{
path: '/home',
name: 'home',
// 懒加载路由
component: () => import('@/pages/home/Index.vue'),
},
{
path: '/login',
name: 'login',
component: () => import('@/pages/login/Index.vue'),
}
]
export default routes
src/router/router.config.js文件
js
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import routes from './router'
const router = createRouter({
// 这里使用hash模式路由
history: createWebHashHistory(),
routes,
})
export default router
注册路由
main.js中注册路由
js
import { createApp } from 'vue'
// 引入路由
import router from './router/router.config.js'
const app = createApp(App)
app.use(router)
挂载路由
app.vue中挂载路由
vue
<template>
<router-view />
</template>
嵌套路由
1、在所需嵌套路由下添加children数组,children中为嵌套路由
这里需要注意,子路由的路径path不能在前面添加 “/”,否则会被认定为一级路由
使用redirec属性用来设置嵌套默认路由,路径必须写完整
json
{
path: '/home',
name: 'home',
component: () => import('@/pages/home/Index.vue'),
children:[
{
path: "menu1",
name: "menu1",
component: () => import('@/pages/menu1/Index.vue')
},
{
path: "menu2",
name: "menu2",
component: () => import('@/pages/menu2/Index.vue'),
}
],
redirect: '/home/menu1',
},
获取当前路由路径
js
import { useRouter } from 'vue-router'
const router = useRouter();
const path = router.currentRoute.value.path;
console.log(path) //结果:http://localhost:3002/#/text/text2 => /text/text2
编程式路由跳转
1、template中跳转方式,直接$router.push()即可
vue
<button @click="$router.push('login')">跳转到登陆页</button>
2、类似get请求,请求参数暴露在地址栏中
使用path定义路径,query传递参数
js
import { useRouter } from 'vue-router'
// 跳转
const router = useRouter();
router.push({
path:'/home',
query:{ id:1 }
})
// 接收参数
const router = useRoute()
console.log('id:'+router.query.id)
3、类似post请求,请求参数不会暴露在地址栏中
使用name定义跳转路由名称,params传递参数
js
import { useRouter } from 'vue-router'
// 跳转
const router = useRouter();
router.push({
name:'home',
params:{ id:1 }
})
// 接收参数
const router = useRoute()
console.log('id:'+router.params.id)
路由守卫
路由守卫分为全局路由守卫,路由独享守卫,组件路由守卫
全局路由守卫
beforeEach(to, from, next):全局前置守卫,路由跳转前触发
- to:即将要进入的目标路由对象
- from:即将要离开的路由对象
- next: next 是一个方法,代表的是是否展示路由页面,如果不使用next方法,那么指定页面无法显示
使用:在进行登录权限时候进行使用,如果没有token,则回到登录页
js
const router = createRouter({
history: createWebHashHistory(),
routes
})
// 全局守卫:登录拦截 本地没有存token,请重新登录
router.beforeEach((to, from, next) => {
// 判断有没有登录
if (!localStorage.getItem('token')) {
if (to.name == "login") {
next();
} else {
router.push('login')
}
} else {
next();
}
});
afterEach(to, from):全局后置守卫,路由跳转后触发
beforeResolve(to, from, next): 全局解析守卫 在所有组件内守卫和异步路由组件被解析之后触发
路由独享守卫
之前的全局守卫,是定义的全局路由守卫,现在的是路由独享的守卫,在配置路由时,写在路由参数内部
- beforeEnter(to,from,next) 路由对象单个路由配置 ,单个路由进入前触发
json
{
path: '/admin',
name: 'admin',
component: () => import('../views/mine/admin.vue'),
//判断是否登陆代码,点击进入admin也面时,路由独享守卫启用
beforeEnter:(to,form,next)=>{
if (!localStorage.getItem('user')) {
if (to.name == "login") {
next();
} else {
router.push('login')
}
} else {
next();
}
}
}
组件路由守卫
beforeRouteEnter(to,from,next)在组件生命周期beforeCreate阶段触发
js
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
}
beforeRouteUpdadte(to,from,next)当前路由改变时触发
js
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to,from,next)导航离开该组件的对应路由时触发
js
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}
使用 watch 监听 $route 对象
vue
<template>
<div>
<!-- 组件内容 -->
</div>
</template>
<script setup>
import { useRoute, useRouter } from 'vue-router'
import { watch } from 'vue'
const route = useRoute()
watch(route, (toParams, previousParams) => {
// 响应路由变化
console.log('路由变化', toParams, previousParams)
}, { deep: true }) // 深度监听以捕获所有变化
</script>
使用 onBeforeRouteUpdate 钩子
vue
<template>
<div>
<!-- 组件内容 -->
</div>
</template>
<script setup>
import { onBeforeRouteUpdate } from 'vue-router'
onBeforeRouteUpdate((to, from) => {
// 在当前路由改变,但是该组件被复用时调用
console.log('路由更新', to, from)
})
</script>