一、前端路由的概念与原理
路由router就是对应关系。分为前端路由和后端路由。
1后端路由
后端路由指的是:请求方式、请求地址与function处理函数之间的对应关系。在node.js中,express理由的基本用法如下:
const express = require('express');
const router = express.Router();
router.get('/user', function(req, res){
//路由处理函数
});
router.post('/user', function(req, res){
//路由处理函数
});
module.exports=router
2.前端路由
spa是一个web网站只有一个唯一的html页面,所有组件的展示与切换都在这唯一的一个页面完成。不同组件之间的切换需要通过前端路由来实现。
前端路由是hash地址和组件之间的对应关系。
3.前端路由的工作方式
用户点击了页面上的路由链接
导致URL地址栏中的hash值发生了变化
前端路由监听到hash地址的变化
前端路由把当前hash地址对应的组件渲染到浏览器中
//页面上的路由链接
<a href=''#/home></a>
//前端路由的对应关系
{path:'#/home',component:Home}
//页面上要展示的组件
<Home/>
4.模拟实现简单前端路由
<template>
<a href="#/box">about</a>
<a href="#/demo">demo</a>
<hr>
<component :is="comName"></component>
</template>
<script >
import Box from "../box/index.vue";
import Demo from "../demo/index.vue";
export default{
components:{
Mato,Demo
},
data(){
return{
comName:""
}
},
created(){
window.onhashchange=()=>{
switch(location.hash){
case '#/box':
this.comName='Box';
break
case '#/demo':
this.comName='Demo';
break
}
}
}
}
二、vue-router
vue-router4.x版本只能结合vue3使用
1.基本使用步骤
a.在项目中安装vue-router
npm install vue-router@next -S
//next是最新版本
b.定义路由组件
c.声明路由链接和占位符
//声明路由链接
<router-link to='/home'>首页</router-link>
//声明路由占位符
<router-view></router-view>
d.创建路由模块
import {createRouter,createWebHashHistory} from "vue-router";
import home from "../views/home/index.vue";
import about from "../views/about/index.vue";
const router=createRouter({
history:createWebHashHistory(import.meta.env.Base_URL),
routes:[
{ path:"/", redirect:"/home" },
{ path:"/home", name:"/home", component:home },
{ path:"/about", name:"/about", component:about }
]
})
export default router;
e.导入并挂载路由
//main.js
import router from "./routers/index.js";
app.use(router)
history:createWebHashHistory(import.meta.env.Base_URL),如果不写()会报错,可以写成history:createWebHashHistory()
2.路由重定向redirect
用户在访问地址a的时候,强制用户跳转到地址c,从而展示特定的组件页面。
{ path:"/", redirect:"/home" },
3.路由高亮
a.router-link-active的类名
被激活的路由链接,默认会应用一个叫做router-link-active的类名。开发者可以使用此类名选择器,为激活的路由链接设置高亮的样式
<template>
<div>
<router-link to="/home">home</router-link>
<router-link to="/about">about</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script setup>
</script>
<style scoped>
.router-link-active{
background-color: red;
color: #fff;
font-weight: bold;
}
</style>
b.linkActiveClass属性
在创建路由的实例对象时,可以基于linkActiveClass属性,自定义路由被激活时所应用的类名
import {createRouter,createWebHashHistory} from "vue-router";
import home from "../views/home/index.vue";
import about from "../views/about/index.vue";
const router=createRouter({
history:createWebHashHistory(import.meta.env.Base_URL),
linkActiveClass:'router-active'
routes:[
{ path:"/", redirect:"/home" },
{ path:"/home", name:"/home", component:home },
{ path:"/about", name:"/about", component:about }
]
})
export default router;
//style.css
.router-active{
background-color: red;
color: #fff;
font-weight: bold;
}
4.嵌套路由
//嵌套路由
{
path:'/about',
component:About,
children:[
{path:'tab1',component:Tab1 },
{path:'tab2', component:Tab2 }
]
}
//嵌套组件
<template>
<router-link to="/about/tab1">tab1</router-link>
<router-link to="/about/tab2">tab2</router-link>
<hr>
<router-view></router-view>
</template>
嵌套路由的重定向
{
path:'/about',
component:About,
redirect:'/about/tab1',
children:[
{path:'tab1',component:Tab1 },
{path:'tab2', component:Tab2 }
]
}
5.动态路由匹配
把hash地址中可变的部分定义为参数项,从而提高路由规则的复用性。
<template>
<div>
<router-link to="/movie/1">movie1</router-link>
<router-link to="/movie/2">movie2</router-link>
<router-link to="/movie/3">movie3</router-link>
<hr>
<router-view></router-view>
</div>
</template>
{
path:'/movie/:id',
component:Movie,
}
<template>
<div>movie</div>
{{ $route.params.id }}
</template>
使用props接收路由参数
为了简化路由参数的获取形式,vue-router允许在路由规则中开启props传参。
{
path:'/movie/:id',
component:Movie,
props:true
}
<template>
<div>movie</div>
{{ id }}
<hr>
</template>
<script>
export default{
props:['id']
}
</script>
6.vue-router中编程式导航api
通过调用api实现导航的方式叫做编程式导航。调用location.href跳转到新页面
通过点击链接实现导航的方式叫做声明式导航。<a/><router-link>标签
a.this.$router.push('hash地址')
跳转到指定hash地址,从而展示对应的组件
<template>
<div>home</div>
<button @click="goToMovie(3)">导航去movie页面</button>
</template>
<script >
export default{
methods:{
goToMovie(id){
this.$router.push(`/movie/${id}`)
}
}
}
</script>
b.this$router.go()
实现导航历史的前进,后退
<template>
<div>movie</div>
{{ id }}
<button @click="goBack">后退</button>
<hr>
</template>
<script>
export default{
props:['id'],
methods:{
goBack(){
this.$router.go(-1)
}
}
}
</script>
7.命名路由(添加name属性)
通过name属性为路由规则定义名称的方式叫做命名路由。
明明路由name必须唯一,不能重复。
{
path:'/movie/:id',
name:'movie',
component:Movie,
props:true
}
<template>
<div>home</div>
<button @click="goToMovie(3)">导航去movie页面</button>
<router-link :to="{name:'movie',params:{id:3}}">导航去movie页面</router-link>
</template>
<script >
export default{
methods:{
goToMovie(id){
this.$router.push({name:'movie',params:{id:id}})
}
}
}
</script>
三、导航守卫
导航首位可以控制路由的访问权限。
1.如何声明全局路由守卫
全局导航首位会拦截每个路由规则,从而对每个路由进行访问权限的控制。
2.路由守卫的3个参数to,from,next
to目标路由对象
from 当前导航正要离开的路由对象
next是一个函数,表示放行。不声明next参数,则默认用户可以访问每一个路由,声明了next参数,则必须调用next()函数,否则不允许用户访问任何一个路由。next(false);强制其停留在当前页面;next(‘’/login);强制其跳转到指定页面
router.beforeEach((to,from,next)=>{
const token = localStorage.getItem('token');
if(to.path==='/main' && !token){
console.log('goHome');
next('/home')
}else{
next()
}
})