【Vue3】 Vue-Router路由和路由导航守卫

前后端分离阶段路由

  • 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的回调函数,创建好的组件实例会作为回调函数的参数传入

猜你喜欢

转载自blog.csdn.net/weixin_44899940/article/details/132312005