Vue3中Router的使用

125 阅读4分钟

安装

npm install vue-router
  • 使用Vue3安装对应的route4版本
  • 使用Vue2安装对应的route3版本

定义(src/router/index.ts)

//导出router
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"

//定义路由信息
const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        name: "Test",
        component: ()=>import("../components/Test.vue")
    },
    {
        path: "/home",
        name: "Home",
        component: ()=>import("../components/Home.vue")
    }
]

const router = createRouter({
    //设置路由模式
    history: createWebHistory(),
    //存放路由信息
    routes
})

//导出
export default router

注册(main.ts)

import router from "./router"
//注册路由
app.use(router)

使用<router-view></router-view>即可显示组件

<router-link></router-link>的使用

  • 可以在不重新加载页面的情况下更改 URL
//通过路由路径跳转
<router-link to="/home"></router-link>
//通过路由名称跳转
<router-link :to="{name: "Test"}"></router-link>

路由模式

createWebHashHistory模式
  • 地址栏带 #
  • 获取路由
window.location.hash
  • 路由跳转
window.location.hash = "/home"
  • 监听浏览器左右箭头的变化,通过hashchange
window.addEventListener("hashchange",(e)=>{
    //参数里面包括newURL,oldURL等参数
    console.log(e)
})
createWebHistory模式
  • 地址栏不带 #
  • 基于H5的history实现的
  • 监听浏览器左右箭头的变化,通过popstate
window.addEventListener("popstate",(e)=>{
    //参数里面包括state下的forward,back,current等参数
    console.log(e)
})
  • 路由跳转
//参数一:想存的东西
//参数二:title---没什么用
//参数三:要跳转的路径
history.pushState({state:1},"","/home")

编程式导航进行路由跳转

//引入路由hook
import { useRouter } from "vue-router"
const router = useRouter()

//路由跳转-----字符串模式
router.push("/home")
//可路由传参-----对象模式
router.push({
    push: "/home"
})
//命名式路由跳转
router.push({
    name: "home"
})

路由历史记录

//添加replace之后,路由跳转不会有历史记录
<router-link replace to="/home"></router-link>
//路由跳转不会有历史记录
router.replace ("/home")
//前进一个历史记录
router.go(1)
//后退一个历史记录
router.go(-1)
router.back()

路由传参

  • query传参
import { useRouter } from "vue-router"
const router = useRouter()

//方式一: query传参
router.push({
    path: "/home",
    query: {
        name: "栗子",
        age: 18
    ]
})
import { useRoute } from "vue-router"
const route = useRoute()

// query取参
console.log(route.query.name)
console.log(route.query.age)
  • params传参
//方式二: params传参
//注意: 必须使用name去传参
//问题:存在内存中,页面一刷新参数会丢失
router.push({
    name: "home",
    params: {
       name: "栗子",
       age: 18
    }
})
//方式二: params取参
console.log(route.params.name)
console.log(route.params.age)
  • 动态路由传参
//定义路由
 {
    //动态路由参数
    path: "/home/:id",
    name: "Home",
    component: ()=>import("../components/Home.vue")
 }
 
 //方式三: 动态路由传参
 router.push({
    name: "home",
    params: {
       id: 666
    }
})
//方式三: 动态路由取参
console.log(route.params.id)
二者的区别
  1. query 传参配置的是 path,而 params 传参配置的是name
  2. query 传参在路由配置不需要设置参数,而 params 必须设置
  3. query 传递的参数会显示在地址栏中
  4. params 传参刷新会丢失值,但是query会保存传递过来的值,刷新不变
  5. 路由配置

嵌套路由

//定义嵌套路由信息
const routes: Array<RouteRecordRaw> = [
    {
        path: "/order",
        component: ()=>import("../components/Test.vue"),
        children: [
            {
                path: "",
                name: "Home",
                component: ()=>import("../components/Home.vue")
            },
            {
                path: "menu",
                name: "Menu",
                component: ()=>import("../components/Menu.vue")
            },
        ]
    },
]
//路由跳转
<router-link to="/order"></router-link>
<router-link to="/order/menu"></router-link>

命名视图&&路由重定向(redirect,3种方式)&&路由别名(alias)

命名视图可以让一个组件具有多个路由渲染出口,命名视图类似于“具名插槽”,并且视图的默认名称也是 default
一个视图使用一个组件渲染,对于同个路由,多个视图就需要多个组件。需正确使用 components 配置 (带上 s)

import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'

//配置路由信息
const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        component: ()=>import("../components/Test.vue")
        redirect:'/order1',    //路由重定向  -----  字符串形式配置
        redirect: { path: "/order1" },     //对象形式配置
        //函数模式(可传参)
        //to为当前父路由的所有信息
        redirect: (to)=>{
            return {
                path: "/order1",
                query: {
                    name: "栗子"
                }
            }
        },
        //路由别名 alias
        //访问/,/test1,/test2,/test3都是会加载"../components/Test.vue"
        alias: ["/test1","/test2","/test3"]
        children: [
            {
                path: "/order1",
                components: {
                    default: () => import('../components/layout/menu.vue')
                }
            },
            {
                path: "/order2",
                components: {
                    header: () => import('../components/layout/header.vue'),
                    content: () => import('../components/layout/content.vue')
                }
           }
        ]
    },
]

const router = createRouter({
    history: createWebHistory(),
    routes
})

export default router

页面使用

<div>
    //展示定义default下的路由
    <router-view></router-view>
    <router-view name="header"></router-view>
    <router-view name="content"></router-view>
</div>

路由导航守卫

全局前置守卫(router.beforeEach)
//to: 去哪
//from: 从哪来
//next(): 跳转到哪块
//next(false): 中断当前的导航
//next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航
 
//定义白名单路径
const whileList = ["/"]

router.beforeEach((to, form, next) => {
    //通过路由元信息种的titie设置页面的标题
    document.title = to.meta.title
    //白名单有值或者储存了token就可以跳转页面
    if(whileList.includes(to.path) || localStorage.getItem("token")){
        next()
    }else{
       //去登录页
       next("/login") 
    }    
})
全局后置守卫(router.afterEach)
//to: 去哪
//from: 从哪来
router.afterEach((to,from)=>{

})

路由元信息(meta)

//需要标注路由元信息的值类型
declare module "vue-router" {
    interface RouteMeta {
        title: string,
        transition: string    //路由过渡动效
    }
}

//定义路由信息
const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        name: "Test",
        component: ()=>import("../components/Test.vue"),
        meta: {
            title: "测试",
            //使用Animate.css动画库中的类名
            transition: ""
        }
    },
    {
        path: "/home",
        name: "Home",
        component: ()=>import("../components/Home.vue"),
        meta: {
            title: "首页",
            transition: ""
        }
    }
]

路由过渡动效

需配置路由元信息中的transition属性
页面使用

<router-view #default="{route,Component}">
        <transition :enter-active-class="`animate__animated ${route.meta.transition}`">
            <component :is="Component"></component>
        </transition>
    </router-view>
    
import "animate.css"

路由滚动行为(scrollBehavior)

当切换到新路由时,想要页面滚到顶部,或者是保持原先的滚动位置,就可以使用路由滚动行为

const router = createRouter({
    history: createWebHistory(),
    //savePosition用来标记距离
    scrollBehavior: (to, from, savePosition) => {
        if(savePosition){
            return savePosition
        }else {
            return {
                top: 0
            }
        }  
    },
})

动态路由

使用场景:后台会返回一个路由表,前端需要重新处理

添加路由
router.addRoute({
    path: "",
    name: "",
    component: ()=>import("")
})
删除路由
//按名称删除路由
router.removeRoute('test')
查看路由所有列表
router.getRoutes()