路由
- 前后端分离阶段路由
- 单页面富应用阶段
- 前端路由如何做到URL和内容进行映射?
- URl的hash(哈希)
- URl的history
- Vue-Router基本使用
- 1,安装Vue-Router
- 2,新建页面router文件下的index.js,路由,导入页面,导入路由,创建路由关系
- 3,main.js
- 3,app.vue里面
- router-link属性
- 路由懒加载分包处理
- 路由routes的其他属性
- 动态路由和路由嵌套
- 1,动态路由的基本匹配
- 2,如果想要在vue页面中取到传的参数
- Not Foned
- 路由的嵌套使用
- 路由的编程式导航
- 导航,router.push方法
- 接收query数据
- router.replace()方法,替换当前页面
- router.back(n)方法,返回上个页面,也可以n个页面
- router.forward(n)方法向前一步,也可以n步
- router.go(n),页面前进或后退,n为正或为负
- history.back(),回溯历史相当于router.go(-1)
- history.forward(),在历史中前进相当于router.go(1)
- 动态管理路由对象
- 动态添加路由
- 动态添加子路由
- 删除路由方式一
- 删除路由方式二
- 删除路由方式三
- 路由对象的其他方法
- 检查路由是否存在
- 获取路由对象中所有的映射路由对象
- 编译警告
- 路由导航守卫
- 前置导航守卫
- 完整的导航解析流程
前后端分离阶段路由
- Ajax的出现,有了前后端分离的开发模式
- 后端提供ApI返回数据,前端通过Ajax获取数据,并且通过js渲染到页面上
- 优点。前后端责任清晰
单页面富应用阶段
- SPA最大的特点就是前后端分离的基础上加一层前端路由
- 也就是前端维护一套路由规则
- 核心,改变URl的同时,页面不进行整体刷新
前端路由如何做到URL和内容进行映射?
- 监听URL的改变
URl的hash(哈希)
- URl的hash也就是锚点(#),本质上式改变window.location的和href属性
- 我们可以通过直接赋值location.hash来改变和href(但是页面不发生刷新)
URl的history
- HTML5新增,有6种模式改变URL而不刷新页面
- replaceState,替换原来的路径
- pushState,使用新的路径
- popState,路径的回退
- go,向前或向后改变路径
- forward,向前改变路径
- back,向后改变路径
Vue-Router基本使用
- 通过Vue-Router构建单页应用(SPA)
- 1,创建路由对象
- 2,建立映射关系
- 3,让路由对象生效
- 4,挂载router
- 5,router-view占位
- 6,router-link路由切换
1,安装Vue-Router
npm install vue-router
2,新建页面router文件下的index.js,路由,导入页面,导入路由,创建路由关系
- createWebHashHistory:指的是用hash模式路由,比如/#/order/detail这种带#的path
- createWebHistory:基于html5原生的history API实现路由
- createMemoryHistory:基于内存信息来隐式管理路由,适用于SSR场景
import { createRouter,createWebHashHistory } from 'vue-router'
//导入
import Home from "../Views/home.vue"
import About from "../Views/about.vue"
//创建路由对象,//建立映射关系
const router = createRouter({
history:createWebHashHistory (),//用于指定采用的模式。目前式哈希模式
routes: [
//一般开发里面都会写一个重定向的路径
{
path: '/', redirect: "/home"
},
{
path: '/home', component: Home
},
{
path: '/about', component: About
}
]
})
//导出
export default router
3,main.js
import { createApp } from 'vue'
import App from './App.vue'
//再次导入,告诉app,注意这里的使用方式
import router from './router/index'
createApp(App).use(router).mount('#app')
3,app.vue里面
<template>
<p>标题</p>
<router-view></router-view>
<div class="nev">
<router-link to="Home">Home</router-link>
<router-link to="about">about</router-link>
</div>
</template>
<script setup>
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
router-link属性
- 1,replace属性,替换属性,不会存在历史里面
<router-link to="Home" replace>Home</router-link>
- 2,to属性,可以是字符串,也可以是对象
<router-link to="Home" replace>Home</router-link>
<router-link :to="{path:'/about'}">about</router-link>
- 3,active-class属性
- 设置激活a元素后应用的class,默认是router-link-active
.router-link-active{
color :blue;
}
- 4,exact-active-class属性
- 链接精准激活时,应用于渲染的的class,默认是router-link-exact-active
路由懒加载分包处理
- 可以提高首屏的渲染效率
//如果想要分包
const Home=()=>import("../Views/hone.vue")
const About=()=>import("../Views/about.vue")
路由routes的其他属性
- name 属性,路由记录的独一无二的名称,页面跳转的时候可以指定name跳转
- meta属性,放自定义的属性
动态路由和路由嵌套
1,动态路由的基本匹配
- 例如:有个组件页面,用户进入需要传用户id,但id是不同的
- 故:在vue router中,可以在路径中使用一个动态字段来实现,称之为 路径参数
- /:参数
2,如果想要在vue页面中取到传的参数
- 在模板里面取
<template>
<div><p>about的参数{{$route.params.id}}</p></div>
</template>
- 在Vue2的api中获取
this.$route.params.id
- 在Vue3的api中获取
- 但存在缺点,来回切换打印只执行一次
<script setup>
import {useRoute} from "vue-router"
//获取router跳转的id
const route = useRoute()
console.log(route.params.id)
</script>
- 解决方法:想在vue3中监听路由router变化
- 添加一个导航守卫,在当前位置即将更新时触发。
<script setup>
import {onBeforeRouteUpdate} from "vue-router"
//获取router跳转的id
onBeforeRouteUpdate((to,from)=>{
console.log(to,from)
console.log("form",from.params.id)
console.log("to",to.params.id)
})
</script>
Not Foned
-
如果想让用户匹配不到页面,将自动显示下面组件
-
想要解析路径,后面加个*,就可以解析为数组
路由的嵌套使用
- 注意,以 / 开头的嵌套路径将被视为根路径。这允许你利用组件嵌套,而不必使用嵌套的 URL。
- 1,在一层路由中添加children[]属性
{
name: "home",
path: '/home',
component: Home,
children: [
{
path: '/about',
component: About
}
]
},
- 2,在home组件中添加
<router-view></router-view>
- 3,路由跳转
路由的编程式导航
导航,router.push方法
接收query数据
router.replace()方法,替换当前页面
router.back(n)方法,返回上个页面,也可以n个页面
router.forward(n)方法向前一步,也可以n步
router.go(n),页面前进或后退,n为正或为负
history.back(),回溯历史相当于router.go(-1)
history.forward(),在历史中前进相当于router.go(1)
动态管理路由对象
动态添加路由
- 使用场景
- 比如根据用户不同的权限,注册不同的路由
- 这个时候可以使用一个方法addRoute
- 类似下面这个 ,如果有权限,则添加路由
let isAdmin = true
if(isAdmin){
router.addRoute({
path:"/Admin",
component:Admin
})
}
动态添加子路由
- router.addRoute(parentName, route)
- 其中parentName为父级路由定义的name字段。
- 注意:子路由path前面不加“/”
- 还得注意,父级路由里必须有占位router-view
let isAdmin = true
if(isAdmin){
router.addRoute({
name:"Admin",
path:"/Admin",
component:Admin
})
router.addRoute('Admin',{
path:"Adminchild",
component:Adminchild
})
}
删除路由方式一
- 添加一个name相同的路由,后者即可覆盖前者的路径,相当于删除前者路由
删除路由方式二
- 通过removeRoute方法,传入路由名称
router.removeRoute('home')
删除路由方式三
- addRoute里面存放的是对象
const delrouter = router.addRoute({
name: "home",
path: '/home',
component: Home,
children: [
{
path: '/about',
component: About
}
]
})
delrouter()
路由对象的其他方法
检查路由是否存在
- router.hasRoute
获取路由对象中所有的映射路由对象
- router.getRoutes()
console.log(router.getRoutes())
编译警告
路由导航守卫
前置导航守卫
- vue-router提供的导航守卫主要是用来通过跳转或取消的方式守卫导航
- 全局的前置守卫beforeEach是在导航触发的时,被回调
-
它有两个参数
- to:即将进入的路由Route对象
- from:即将离开的路由Route对象
- 还有一个可选的第三个参数next,vue2中来决定如何进行跳转的
-
它有返回值
- false,取消当前导航
- 不返回或者undefined,进行默认导航
- 返回一个路由地址
-
可以是一个string类型的路径
-
可以是一个对象,对象中包含path,query,params等信息
// 路由导航拦截
// - 进行任何的路由跳转之前,传入到beforeEach中的函数都会被回调
router.beforeEach((to,from)=>{
//不写条件会在登录页陷入死循环
if(to.path!='/login'){
return "/login"
}
})
- 常见使用场景
- 进入home页面前,判断用户是否登录
// 路由导航拦截
router.beforeEach((to, from) => {
const token = localStorage.getItem("token")
if (!token && to.path == '/home') {
return "/login"
}
return undefined//否则默认导航
})
完整的导航解析流程
- 1,导航被触发
- 2,在失活的组件里调用beforeRouteLeave()守卫
- 3,调用全局的beforeEach()守卫
- 4,在重用的组件里调用beforeRouteUpdate()守卫,不能使用组件实例this
- 5,在路由配置调用beforeEnter()
- 6,解析异步路由组件()=>import(…/xxx)
- 7,在被激活的组件里调用beforeRouterEnter()
- 8,调用全局的beforeReasolve(),组件被解析之后,在跳转之前
- 9,导航被确认
- 10,调用全局的afterEach()钩子,
- 11,触发DOM更新
- 12,调用beforeRouteEnter()守卫中传给next的回调函数,创建好的组件实例会作为回调函数的参数传入