【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. 在入口文件(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')

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>

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")
    }
]

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")
    }
]

使用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>

12.4 路由中的query参数

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

使用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>

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")
    }
]


.

12.6 嵌套路由

在父组件中

<template>
    <div>
        <h1>Parent组件</h1>
        <router-link to="/parent/children1">go to children1</router-link>
        <br>
        <router-link to="/parent/children2">go to chiildren2</router-link>
        <p>点击切换展示嵌套组件的内容</p>
      	<!-- 进行占位 -->
        <router-view></router-view>
    </div>
</template>

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

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

命名视图

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

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')
        }
    }
]

 <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>

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>


.

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')
    }
]

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>

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')
    }
]

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>

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')

路由独享守卫

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

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
            }
        }
    }
]

12.13 路由元信息

// 在使用TS的时候可以使用以下的方法去定义路由元信息的类型
declare module 'vue-router'{
  interface RouteMeta {
    show:boolean
  }
}

const routes: Array<RouteRecordRaw> = [
    {
        path:'/',
        redirect:'/login',
        meta:{
        	show:true
        }
    }
]


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>

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
            }
        }
    }
})


12.16 动态路由

import {useRouter} from 'vue-router'
const $router = useRouter()
$router.addRoute({
  path:'/xxx',
  name:'xxx',
  component:()=>import('../xx/xx')
})

总结

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值