Vue路由从入门到精通


Vue全家桶包括Vue核心语法(Vue Core)、Vue-Router、Vuex(Pinia),这篇文章笔者就从浅入深的聊聊Vue-Router,废话没有,全是干货。

简单搭建一个Vue路由的流程

  1. 安装Vue-Router

    npm install -S vue-router

  2. 在项目的新建src/router/index.js文件

    // 导入两个必要的函数
    import { createRouter, createWebHashHistory } from 'vue-router'
    
    // 导入对应的组件
    import Home from '../views/Home.vue'
    
    // 创建对应关系
    const routes = [
        { path: '/', redirect: '/home' }, // redirect 是路由重定向
        { path: '/home', component: Home }
    ]
    
    const router = createRouter({
        routes, // routes: routes 的高级写法
        // createWebHashHistory 是hash模式,在服务端不需要配置,比较方便。
        // 还有一种H5新增的history模式,区别不多赘述,也不再演示。
        history: createWebHashHistory()
    })
    
    // 导出路由配置文件
    export default router
  3. 在项目main.js中使用路由

    // 省略其他的代码
    // 导入路由配置文件
    import router from './src/router'
    
    import { createApp } from 'vue'
    const app = createApp()
    
    // 挂载路由配置
    app.use(router)
    
    app.mount('#app')
  4. 在项目App.vue中使用路由

    路由占位符<router-view></router-view>

    <template>
        <!-- 占位符 渲染的路由组件的位置 !-->
        <router-view></router-view>
    </template>

    路由跳转使用<router-link></router-link>

    <template>
        <!-- to属性代表要跳转的路径  !-->
        <router-link to="/home">首页</router-link>
        <router-link to="my">我的</router-link>
    </template>

路由基本使用的补充

  1. 路由重定向

    通常情况下用户一开始访问的是/根路径是没有组件展示的,可以使用redirect属性设置路由重定向到另一个路由地址

    routes: [
        // 路由重定向到 /home路由
        { path: '/', redirect: '/home' },
        { path: '/home', component: Home }
    ]
  2. 路由模式

    Vue-Router路由模式有hash模式和history模式

    hash模式的使用上文所介绍,下面介绍history模式的基本使用

    // 在 src/router/index.js 文件中
    // 省略其他代码
    
    // 引入 createWebHistory history模式
    import { createRouter, createWebHistory } from 'vue-router'
    
    const router = createRouter({
        routes: [{},{}],
        history: createWebHistory()
    })
    
    export default router
  3. router-link的选项

    to属性跳转的路径都有记录,可以通过浏览器的后退键退回上一个页面。

    还可以传递对象:to={ path: '/home' }

    replace属性跳转路径之后不会形成一个记录 ,不能通过浏览器的后退键退回上一个页面。

    active-class属性可以自定义选择的选项都是类名,active-class="active"表示自定义点击的类名为active

    exact-active-class属性用于嵌套路由中的精确匹配的一个类名。

路由懒加载

路由懒加载可以使得页面加载速度更快,使用import函数,其是一个Promise,核心原理是分包加载。

/* webpackChunkName: 'home' */这是一个魔法注释,用于webpack打包过程中对于分包名称的修改。

// import函数导入组件
// /* webpackChunkName: 'home' */ 在webpack打包时重命名
const Home = () => import(/* webpackChunkName: 'home' */'../views/Home.vue')

const routes = [
    {
        path: '/home',
        component: Home
    },
    // 另外一种写法 不用单独导入用变量接收
    // 依旧可以使用魔法注释
    {
        path: '/about',
        component: () => import('../views/About.vue')
    }
    
]

路由的其他属性

  1. name属性

    路由记录独一无二的值。

  2. meta属性

    自定义的数据

{
    name: 'home,  // 独一无二的名称
    path: '/home'
    component: () => import(),
    meta: {
        title: '首页' // meta是自定义的数据
    }
}

动态路由

有些路由需要匹配一个相同的组件,如果路由有很多,一个一个写不现实,就可以使用动态参数自动匹配,这就是动态路由

{
    path: '/user/:id', // :id 就是用来动态匹配的一个参数
    component: Home
}

获取动态路由的参数

  1. template模板中可以使用$route.params.id获取相应的参数。
  2. script 节点中获取参数

    1. options API 中使用this.$route.params.id获取相应的参数
    2. composition API 中方法具体如下:

      import { useRoute } from 'vue-router'
      
      const route = useRoute()
      
      const id = route.params.id

设置 404 Not Found 页面路由

当路径错误时提示用户,使用pathMatch()可以实现此功能。

// 404 路由放在路由表最后一项
[
    {},
    ...,
    // 404 路由
    {
        path: '/:pathMatch(.*)',
        component: () => import('404页面的加载') // 路由懒加载
    },
]

如果path: '/:pathMatch(.*)*',则会将路径以/分割为一个数组,不加*则不会分割为数组。

url: 123/223/aaa
解析为
["123", "223", "aaa"]

路由嵌套

使用children属性进行路由嵌套。

[
    {
        path: '/home',
        component: ,
        children: [
            // 依旧可以使用 redirect 属性来重定向路由
            { path: '/home', redirect: '/home/product' },
            {
                path: 'product',  // 相当于 /home/product
                component: , // 依旧可以使用路由懒加载
                // 还可以嵌套
                children: [
                    {},
                    {}
                ] 
            },
        ]
    }
]

Home.vue组件中添加路由占位符切换对应的组件

<template>
    <div>
        Home.vue
    </div>
    <router-view></router-view>
</template>

编程式导航

在使用其他标签时,无法使用to属性进行路由的跳转,可用的方法有pushreplace 等等。在composition API中使用编程式导航的方法如下:

import { useRouter } from 'vue-router'

const router = useRouter()

// 使用 push跳转 有记录 可退回
router.push('/about')
// 或者 以对象的形式进行跳转 可以传参数
router.push({
    path: '/about',
    query: {
        name: hhh,
        age: 15
    }
})

// 使用 replace 跳转 替换记录 不可退回
router.replace('/home')

// 前进 or 后退
router.forward  // 前进
router.back()  // 后退

router.go(-1) // 向后退一层
router.go(1)  // 向前进一层

pushrepalce的区别:

  • push进行跳转会有记录,可以后退
  • replace 进行跳转会覆盖掉之前的记录,不可后退

动态添加路由

对于不同角色适当的添加一些新的路由。使用addRoute()函数可以实现此操作,具体操作如下:

  1. 添加一级路由

    const router = createRouter({
        routes: [],
        ...
    })
    
    let isAdmin = true
    
    // 如果 isAdmin 为真,则新增一条路由
    if (isAdmin) {
        router.addRouter({
            path: '/admin',
            component: () => import()
        })
    }
  2. 添加子路由

    addRoute('父路由的name', {...}) 用于新增子路由

    const router = createRouter({
        routes: [
            {name: 'home', path: '/home'}
        ],
        ...
    })
    
    let isAdmin = true
    
    // 如果 isAdmin 为真,则新增一条子路由
    if (isAdmin) {
       router.addRoute('home', {
           path: 'vip',
           component: () => import()
       })
    }
    
    // 另外一种写法
    const vipRoute = {
         path: 'vip',
         component: () => import()
    }
    
    if (isAddmin) {
        router.addRoute('home', vipRoute)
    }

删除路由

  1. 添加一个相同 name 的路由

    router.addRouter({ path: '/home', name: 'home', component: Home })
    // 会覆盖之前的路由,因为它们的 name 必须唯一
    router.addRouter({ path: '/other', name: 'home', component: Other })
  2. 通过 removeRoute()方法,传入路由的名称

    router.addRouter({ path: '/home', name: 'home', component: Home })
    // 删除路由
    router.removeRoute('home')
  3. 通过 addRoute() 方法的返回值调用删除路由

    const removeRoute = router.addRoute({})
    
    // 删除路由 如果存在的化
    removeRoute()

路由其他方法补充

  • router.hasRoute() :检查路由是否存在
  • router.getRoutes() :获取一个包含所有路由记录的数组。

路由导航守卫

全局前置守卫

beforEach(() => {})它有三个参数:

  • to:即将进入的路由Route对象
  • from:即将离开的路由Route对象
  • next:符合守卫的放行条件,放行next()Vue3 不推荐使用

它的返回值:

  • false:取消当前导航
  • 不返回或者undefined:进行默认导航
  • 返回一个路由地址:

    • 可以是一个string类型的路径
    • 可以是一个对象,对象中包含path、query、params等信息

具体演示:

场景:进入路径 my 对应的组件必须登录(token值不为空)。

const router = createRouter({})

// 全局前置守卫
router.beforeEach((to, from) => {
    const token = localStorage.getItem('token')
    // 如果没有 token 且 访问的路径为 my 则被强制跳转到 login 路由对应的组件
    if (!token && to.path === '/my') {
        return '/login'
    }
})

声明:极客角度|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - Vue路由从入门到精通


拒绝拖延,勇于表达!