• 【Vue3】第十二部分 Vue-Router 4 (路由)


    Vue3】第十二部分 Vue-Router 4 (路由)



    12. Vue-Router 4 (路由)

    安装:npm install vue-router@4

    12.1 基本的使用

    在Vue3中使用路由和Vue2其实有挺多的变化

    1. src/router/index.ts
    // 导入创建一些方法,例如创建路由器
    import {createRouter,createWebHashHistory,RouteRecordRaw} from "vue-router"
    
    // 定义一个基本的路由表
    // RouteRecordRaw 用来限制路由表的类型
    const routes:Array<RouteRecordRaw> = [
        {
            path:'/home',
            // 在这里使用路由懒加载
            component: ()=>import('../components/Home.vue')
        },
        {
            path:'/test',
            // 在这里使用路由懒加载
            component: ()=>import('../components/Test.vue')
        },
    ]
    
    // 创建路由器,在这里可以配置很多东西
    const router = createRouter({
        // 使用history模式,也就是hash模式
        history:createWebHashHistory(),
        // key-value一致
        routes
    })
    
    // 暴露路由
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    1. 在入口文件(main.ts)中去使用router
    import { createApp } from 'vue'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    // 在这块需要注意:有先后顺序的问题,需要先使用路由再挂载
    const app = createApp(App)
    // 先使用路由器
    app.use(router)
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    3.举例 在App组件中使用

    <template>
      <div>
        <p>1111</p>
        <!-- 相当于一个坑,将内容放入这个坑中 -->
        <router-view></router-view>
        <p>2222</p>
        <router-link to="/home">跳转至home</router-link>
        <br>
        <router-link to="/test">跳转至test</router-link>
      </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    12.2 捕获所有路由或者是404 Not Found 页面

    const routes:Array<RouteRecordRaw> = [
        {
            path:'/home',
            // 在这里使用路由懒加载
            component: ()=>import('../components/Home/index.vue')
        },
        {
            // 匹配任意的路径,404页面
            path:'/:path(.*)',
            component:()=>import("../components/NotFound.vue")
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    12.3 路由中的params参数

    src/router/index.ts

    const routes:Array<RouteRecordRaw> = [
        {
            path:'/home',
            // 在这里使用路由懒加载
            component: ()=>import('../components/Home/index.vue')
        },
        {
            // 动态路由,也就是params参数,通过 :xx,进行占位
            path:'/about/:id',
            component:()=>import('../components/About/index.vue')
        },
        {
            // 匹配任意的路径,404页面
            path:'/:path(.*)',
            component:()=>import("../components/NotFound.vue")
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    使用useRoute取到params参数

    <script lang="ts" setup>
        import {useRoute} from "vue-router"
        // 可以利用useRoute,拿到params参数
        const id = useRoute().params.id        
    </script>
    
    <template>
        <div>
            <h1>About组件</h1>
            <p>传入的参数为 : {{id}}</p>
        </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    12.4 路由中的query参数

    http://localhost:5173/#/news?name=Lihua&age=22
    
    • 1

    使用useRoute取到query参数

    <script lang="ts" setup>
        import {useRoute} from "vue-router"
        const data = useRoute().query
    </script>
    
    <template>
        <div>
            <h1>News组件</h1>
            <h3>姓名: {{data.name}} --- {{data.age}}</h3>
        </div>
    </template>
    
    <style scoped lang='less'>
    </style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    12.5 路由正则

    在路由中可以使用正则表达式

    const routes:Array<RouteRecordRaw> = [
        /*
            补充一下正则的一些基本点
            + : 可以是一个或者多个
            * : 可以是0个或者多个
            ? : 可以是0个或者1个 
         */
        {
            // ()里面写正则表达式,目的是限制传入参数
            // 例如: 传入的参数必须是数字,数字可以是一个或者多个
            path:'/home/:id(\\d+)',
            // 在这里使用路由懒加载
            component: ()=>import('../components/Home/index.vue')
        },
        {
            // 可以有1个或者多个参数传入,注意:这个时候就不需要加括号
          	// 不要和上面搞混了
            path:'/news/:id+',
            component:()=>import("../components/News/index.vue")
        },
        {
            // 可以0个或者有多个参数传入
            path:'/message/:id*',
            component:()=>import("../components/News/index.vue")
        },
        {
            // 可以0个或者1个参数传入
            path:'/add/:id?',
            component:()=>import("../components/News/index.vue")
        },
        {
            // 动态路由参数,也就是params参数,通过 :xx,进行占位
            path:'/about/:id',
            component:()=>import('../components/About/index.vue')
        },
        {
            // 匹配任意的路径,404页面
            path:'/:path(.*)',
            component:()=>import("../components/NotFound.vue")
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41


    .

    12.6 嵌套路由

    在父组件中

    <template>
        <div>
            <h1>Parent组件h1>
            <router-link to="/parent/children1">go to children1router-link>
            <br>
            <router-link to="/parent/children2">go to chiildren2router-link>
            <p>点击切换展示嵌套组件的内容p>
          	
            <router-view>router-view>
        div>
    template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    src/router/index.ts

    // 导入创建一些方法
    import {createRouter,createWebHashHistory,RouteRecordRaw} from "vue-router"
    
    // 定义一个基本的路由表
    const routes:Array<RouteRecordRaw> = [
      	// 路由嵌套
        {
            path:'/parent',
            component:()=>import("../components/Parent.vue"),
          	// children中定义嵌套路由的基本信息
            children:[
                {
                  	// 路径不需要写/
                    path:'children1',
                    component:()=>import("../components/Children1.vue")
                },
                {
                    path:'children2',
                    component:()=>import("../components/Children2.vue")
                },
            ]
        },
        {
            // 匹配任意的路径,404页面
            path:'/:path(.*)',
            component:()=>import("../components/NotFound.vue")
        }
    ]
    
    // 创建路由器,在这里可以配置很多东西
    const router = createRouter({
        // 使用history模式,也就是hash模式
        history:createWebHashHistory(),
        // key-value一致
        routes
    })
    
    // 暴露路由
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    12.7 命名路由和命名视图

    命名路由

    import {createRouter,createWebHashHistory} from "vue-router"
    
    // 定义一个基本的路由表
    const routes:Array<RouteRecordRaw> = [
        {
            path:'/parent',
            component:()=>import("../components/Parent.vue"),
            children:[
                {
                    // 命名路由
                    name:'children1',
                    path:'children1/:id?',
                    component:()=>import("../components/Children1.vue")
                },
                {
                    path:'children2',
                    component:()=>import("../components/Children2.vue")
                },
            ]
        }
    ]
    
    // 创建路由器,在这里可以配置很多东西
    const router = createRouter({
        // 使用history模式,也就是hash模式
        history:createWebHashHistory(),
        // key-value一致
        routes
    })
    
    // 暴露路由
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    命名视图

    应用场景:当进行路由跳转的时候需要同时展示多个组件,并且所展示的位置不同

    const routes:Array<RouteRecordRaw> = [
        {
            path:'/',
            // 注意这里写的是components,因为展示多个组件所以要+s,并且写成对象的形式
            components:{
                // default:默认展示的组件
                default:()=>import('../components/main.vue'),
                // 这里的key值需要和router-view中的name属性值对应,才能进行展示
                Slide:()=>import('../components/Slide.vue'),
                Top:()=>import('../components/Top.vue')
            }
        }
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
     <div>
       <h1>路由视图</h1>
       <router-view name="Top"></router-view>
       <router-view name="Slide" :style="{float:'left'}"></router-view>
       <router-view :style="{display:'flex'}"></router-view>
     </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    12.8 编程式路由导航

    <script lang="ts" setup>
    import { useRouter, useRoute } from 'vue-router';
    // useRoute是拿到路由中的基本信息
    // useRouter是对路由进行跳转控制
    // inject() can only be used inside setup() or functional components.
    // 报上述的警告,原因是useRoute和useRouter需要在setup()中或者是功能性函数中使用
    // 所以可以在提前定义好
    const $route = useRoute()
    const $router = useRouter()
    
    // 进行路由跳转
    const handlePush = (id: number) => {
        if (id === 1) {
            // 在这里需要注意:
            // 在使用编程式路由导航时,使用params参数不要使用path,而用name(命名路由的形式)
            // 否则会报警告Path "/parent/children1" was passed with params but they will be ignored. Use a named route alongside params instead.
            $router.push({ name:'children1', params: { id } })
        } else {
            $router.push({ path: '/parent/children2', query: { id } })
        }
    }
    
    const previousBack = (type:number) =>{
        if(type){
            // 也可以用forward(),实际上这个函数就是调用go(1)
            $router.go(type)
        }else{
            // 也可以用back(),实际上这个函数就是调用go(-1)
            $router.go(type)
        }
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32


    .

    12.9 重定向和取别名

    const routes:Array<RouteRecordRaw> = [
        {
            path: '/home',
            // 重定向,当访问/home重定向到/
            redirect: '/',
          	// 对象的形式
          	redirect:{
              path:'/'
            },
          	// 函数形式
          	redircet:to=>{
              // to可以拿到路由的信息
              if(to.path === 'xxx')
                {
                   return {
                			path:'/',
               				query:{
                  			name:''
                			}
              			}
                }
             
            }
        },
        {
            path:'/parent',
            // 取别名,也可以通过别名进行跳转
            // alias:'/father',
            // 可以取多个别名
            alias:['/father','/fuqin'],
            component:()=>import('../components/parent.vue')
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    12.10 路由传参

    <script lang="ts" setup>
    import { data } from "../shopdata.json"
    import { useRouter } from "vue-router"
    type Ishop = {
        id: number;
        name: string;
        price: number;
    }
    const $router = useRouter()
    const handleDetail = (item: Ishop) => {
       // query传参
        $router.push({
            path: '/detail',
            query: item
        })
      
        // params传参,用命名路由的方式进行传参,记得进行占位
         $router.push({
             name:'detail',
           	 // params:item
           	// 如果直接传的话,当刷新的时候数据会丢失,为了解决这个办法,可以使用动态路由参数,就是这种方式
           // 并且需要在路由中进行占位
             params:{
                 id:item.id,
                 name:item.name,
                 price:item.price
             }
         })
    }
    </script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    12.11 路由组件传参

    要区分路由传参和路由组件传参是不一样的

    路由组件传参:接收到的路由参数,在组件中可以使用props进行接收

    // 布尔模式
    const routes:Array<RouteRecordRaw> = [
        {
            path:'/test/:id/:name/:age?',
            // 开启布尔模式
            // 当 props 设置为 true 时,route.params 将被设置为组件的 props。
            props:true,
            component:()=>import('../components/test.vue')
        }
    ]
    
    // 对于有命名视图的路由,必须要对每一个命名视图取定义props
    const routes:Array<RouteRecordRaw> = [
      {
        path: '/user/:id',
        components: { default: User, sidebar: Sidebar },
        props: { default: true, sidebar: false }
      }
    ]
    
    // 函数模式
    // 定义一个基本的路由表
    const routes:Array<RouteRecordRaw> = [
        {
            path:'/measure/:id',
            // 函数模式
            props:(route:any)=>{
                // route可以拿到路由的相关信息
                // 可以在这里做一些判断
                if(route.params.id){
                    return {
                        dataProps:route.params.id
                    }
                }
            },
            component:()=>import('../components/measure.vue')
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    props接收路由传入的参数

    <script lang="ts" setup>
        // 使用defineProps(['key']),返回的是一个对象
        const params = defineProps(['id','name','age'])
    </script>
    
    <template>
        <div>
            <p>Test组件</p>
            <p>传入的参数为:{{params.id}} --- {{params.name}}  --- {{params.age === '' ? '这是个人的隐私' : params.age}}</p>
        </div>
    </template>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    12.12 路由守卫

    全局前置路由守卫

    例如:在做登录页面的时候,如果没有进行登录成功是不能访问其他的页面

    import { createApp } from 'vue'
    import ElementPlus from 'element-plus'
    import 'element-plus/dist/index.css'
    import './style.css'
    import App from './App.vue'
    import router from './router'
    // 在这块需要注意:有先后顺序的问题,需要先使用路由再挂载
    const app = createApp(App)
    const whilePath = ['/login']
    app.use(router)
    app.use(ElementPlus)
    // 在挂载之前使用全局路由守卫,必须要有token值才可以跳转
    router.beforeEach((to,from,next) =>{
        if(whilePath.includes(to.path) || localStorage.getItem('token')){
            next()
        }else{
            next('/')        
        }
    })
    app.mount('#app')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    路由独享守卫

    例如:登录成功后,禁止登录页面

    const routes: Array<RouteRecordRaw> = [
        {
            path:'/',
            redirect:'/login'
        },
        {
            path:'/home',
            component:()=>import('../components/home.vue')
        }
        ,
        {
            path: '/login',
            component: () => import('../components/Login.vue'),
            // 独享路由守卫
            beforeEnter:(to,from) =>{
                console.log(to,from);
                if(localStorage.getItem('token')){
                    return false
                }
            }
        }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    12.13 路由元信息

    // 在使用TS的时候可以使用以下的方法去定义路由元信息的类型
    declare module 'vue-router'{
      interface RouteMeta {
        show:boolean
      }
    }
    
    const routes: Array<RouteRecordRaw> = [
        {
            path:'/',
            redirect:'/login',
            meta:{
            	show:true
            }
        }
    ]
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    12.14 路由过渡效果

    <div>
        <!-- 路由过渡效果 -->
        <!-- 
          在router4中可以使用#default="{route,Component}"
          结构出当前的组件和路由信息
        -->
        <router-view #default="{route,Component}">
          <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
            <component :is="Component"></component>
          </transition>
        </router-view>
      </div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    12.15 滚动行为

    / 创建路由器,在这里可以配置很多东西
    const router = createRouter({
        // 使用history模式,也就是hash模式
        history: createWebHistory(),
        // key-value一致
        routes,
        scrollBehavior:(to,from,savePosition) =>{
            // savePosition能自动去记住当前的位置
            if(savePosition){
                return savePosition
            }else{
                return {
                    top:0
                }
            }
        }
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    12.16 动态路由

    import {useRouter} from 'vue-router'
    const $router = useRouter()
    $router.addRoute({
      path:'/xxx',
      name:'xxx',
      component:()=>import('../xx/xx')
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    总结

    以上就是今天要讲的内容,希望对大家有所帮助!!!

  • 相关阅读:
    AVR 单片机 调试环境 JTAG MKII
    预训练Bert添加new token的问题
    如何使用Cygwin编译最新版的Redis源码,生成适用于Windows的Redis
    Deep Residual Learning for Image Recognition--Kaiming He
    面试题及其衍生知识点
    nginx反向代理,用户访问服务器1的80端口,请求转发至服务器2,3的8882端口
    提升协作效率:钉钉流程与低代码平台的无缝对接
    WindivertDotnet快速发Ping
    Linux: 如何命令行安装R包
    获取sku详细信息 API 返回值说明
  • 原文地址:https://blog.csdn.net/Trees__/article/details/126908749