1、基本使用
1、安装路由依赖模块
npm install vue-router@4
2、在src文件夹下新建router文件夹,在router文件夹下新建router.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
3、在src文件夹下新建router.config.js文件
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import routes from './router'
const router = createRouter({
// 这里使用hash模式路由
history: createWebHashHistory(),
routes,
})
export default router
4、main.js中注册路由
import { createApp } from 'vue'
// 引入路由
import router from './router.config'
const app = createApp(App)
app.use(router)
5、app.vue中挂载路由
<template>
<router-view />
</template>
登陆页效果
2、编程式路由跳转
vue3中路由跳转和vue2中类似,也是使用router.push方法
1、template中跳转方式,直接$router.push()
即可
<button @click="$router.push('login')">跳转到登陆页</button>
2、类似get请求,请求参数暴露在地址栏中
使用path定义路径,query传递参数
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传递参数
import { useRouter } from 'vue-router'
// 跳转
const router = useRouter();
router.push({
name:'home',
params:{ id:1 }
})
// 接收参数
const router = useRoute()
console.log('id:'+router.params.id)
3、嵌套路由
1、在所需嵌套路由下添加children数组,children中为嵌套路由
这里需要注意,子路由的路径path不能在前面添加 “/”,否则会被认定为一级路由
使用redirec
属性用来设置嵌套默认路由,路径必须写完整
{
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',
},
2、在home.vue组件中使用嵌套路由,为了页面美观,这里使用了element-plus中的el-menu菜单组件,这里可以直接使用 router-link
完成二级路由切换,也可以使用编程式路由跳转。除此之外,别忘了在内容展示区域使用 router-view
注册
<template>
<div class="home">
<el-container>
<el-header>
</el-header>
<el-container>
<el-aside width="160px">
<el-menu active-text-color="#ffd04b"
background-color="#545c64"
class="el-menu-vertical-demo"
default-active="菜单一"
text-color="#fff">
<!-- 主要代码 -->
<el-menu-item :index="item.name"
v-for="(item,index) in memuList"
:key="item.name"
@click="goRouter(item)">
<span>{{item.name}}</span>
<!-- 直接使用<router-link>完成二级路由切换 -->
<!-- <router-link :to="item.path">{{item.name}}</router-link> -->
</el-menu-item>
</el-menu>
</el-aside>
<el-main>
<!-- 在内容展示区域使用router-view注册 -->
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
// 菜单列表
let memuList = ref([
{ name: '菜单一', path: '/menu1' },
{ name: '菜单二', path: '/menu2' }
])
// 编程式路由跳转
const goRouter = (item) => {
router.push(`/home${item.path}`)
}
</script>
嵌套子路由1
嵌套子路由2
4、动态路由
在做后台管理系统时,经常会遇到有些页面只有管理员能访问,普通用户是不能访问的,这时候就要对路由进行限制,
比如菜单三的管理页面只有管理员能够访问,其他人员不能访问
具体实现方法:
- 将只有管理员能访问的manage管理页面设为动态路由
新建dynamicRoute.js,存储动态路由,因为这里的manage作为二级子路由被添加的,所以这里的path不能加上'/'
//动态路由
const manage = {
path: 'manage',
name: 'manage',
component: () => import('@/pages/manage/Index.vue'),
}
export default manage
- 用户登录后,通过接口获取到用户的登录身份,如果为管理员身份,使用
router.addRoute()
方法来添加动态路由
这里manageRoute是作为home的二级路由添加的,因此这里指定home就能将manageRoute添加为home的子路由
// 添加动态路由
import { useRouter } from 'vue-router'
import manageRoute from "@/router/dynamicRoute";
//这里调用接口获取用户身份就省略不写了
......
const router = useRouter()
// 这里manageRoute是作为home的二级路由添加的,因此这里指定home就能将manageRoute添加为home的子路由
router.addRoute("home", manageRoute)
- 页面刷新后,会造成动态路由消失,因此在app.vue页面监听router变化,重新添加路由
<script>
import manage from "@/router/dynamicRoute"
export default {
watch: {
$route: {
async handler (newVal) {
/* 在4.x版本中需手动调用router.replace方法重定向,
因为动态路由页面刷新时,matched的值为空;
在3.x版本中,刷新页面添加异步路由,matched有值,不需要再重定向 */
this.$router.addRoute("home", manage)
/* 在动态路由页面刷新时,matched数组为空 */
if (!newVal.matched.length && newVal.fullPath === "/home/manage") {
await this.$router.replace("/home/manage")
}
},
},
},
};
</script>
4、路由守卫
路由守卫分为全局路由守卫,路由独享守卫,组件路由守卫
(1)全局路由守卫
beforeEach(to, from, next)
:全局前置守卫,路由跳转前触发
to
:即将要进入的目标路由对象
from
:即将要离开的路由对象
next
: next 是一个方法,代表的是是否展示路由页面,如果不使用next方法,那么指定页面无法显示
使用:在进行登录权限时候进行使用,如果没有token,则回到登录页
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)
: 全局解析守卫 在所有组件内守卫和异步路由组件被解析之后触发
(2)路由独享守卫
之前的全局守卫,是定义的全局路由守卫,现在的是路由独享的守卫,在配置路由时,写在路由参数内部
beforeEnter(to,from,next)
路由对象单个路由配置 ,单个路由进入前触发
{
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();
}
}
}
(3)组件路由守卫
beforeRouteEnter(to,from,next)
在组件生命周期beforeCreate阶段触发
beforeRouteEnter (to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
}
beforeRouteUpdadte(to,from,next)
当前路由改变时触发
beforeRouteUpdate (to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
// 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
// 可以访问组件实例 `this`
},
beforeRouteLeave(to,from,next)
导航离开该组件的对应路由时触发
beforeRouteLeave (to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
}