Vue 3 路由配置使用与讲解

发布于:2025-04-17 ⋅ 阅读:(25) ⋅ 点赞:(0)

在现代前端开发中,单页应用(SPA)已成为主流趋势,Vue.js 作为一款优秀的 JavaScript 框架,在构建 SPA 方面表现出色。Vue Router 作为 Vue.js 官方的路由管理器,与 Vue.js 核心深度集成,极大地简化了单页应用的路由管理工作。在 Vue 3 中,Vue Router 也进行了升级,带来了新特性与改进,本文将全面深入地介绍 Vue 3 中路由的配置和使用。​

一、安装和基础设置​

(一)安装 Vue Router​

首先,确保你的项目已经初始化好 Vue 3 环境。若尚未安装vue-router,可以通过 npm 或 yarn 进行安装,以 npm 为例,安装命令如下:

npm install vue-router@4

这里指定安装@4版本,是因为 Vue 3 搭配的是 Vue Router 4,它在功能和使用方式上与之前版本有所不同。​

(二)创建路由实例​

安装完成后,通常在项目的src目录下创建一个router文件夹,在其中新建index.js文件用于配置路由实例。代码示例如下:

// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
// 导入路由对应的组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'

const routes = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  }
]

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes
})

export default router

上述代码中,createRouter用于创建路由实例,createWebHistory则用于启用 HTML5 History 模式,该模式下 URL 更加美观,没有#符号,但需要服务器进行相应配置,否则刷新页面可能出现 404 错误。若不想配置服务器,也可使用createWebHashHistory模式,即 Hash 模式,URL 会带有#符号,兼容性更好。routes数组定义了路由的映射关系,每个对象包含path(路径)、name(路由名称,方便通过名称进行导航)和component(路径对应的组件)。​

(三)在 Vue 应用中使用路由​

在main.js文件中引入并使用上述创建好的路由实例,代码如下:

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

通过app.use(router)将路由实例挂载到 Vue 应用中,这样整个应用就具备了路由功能。同时,在根组件App.vue中,需要使用<router - view>标签作为路由出口,用来渲染匹配到的组件。例如:

<template>
  <div id="app">
    <router - view></router - view>
  </div>
</template>

二、路由配置详解​

(一)路由模式​

Vue Router 4 支持两种主要的路由模式:Hash 模式和 History 模式。​

  1. Hash 模式:使用 URL 的 hash(即#号后面的部分)来模拟一个完整的 URL,当#号后面的内容发生变化时,不会向服务器发送请求。这种模式兼容性好,在一些不支持 HTML5 History API 的老旧浏览器中也能正常使用。配置方式如下:
    const router = createRouter({
      history: createWebHashHistory(),
      routes: [...]
    })

  2. History 模式:利用 HTML5 History API 来实现 URL 的变化,通过pushState和replaceState方法改变浏览器地址栏的 URL,同时不会重新加载页面。这种模式下的 URL 更加简洁美观,符合现代 Web 应用的需求,但如前文所述,需要服务器进行配置,确保所有路径都能正确回退到index.html。配置代码如下:

    const router = createRouter({
      history: createWebHistory(),
      routes: [...]
    })
    (二)路由匹配​
  3. 动态路由匹配:在实际应用中,经常需要根据不同的参数来展示不同的内容,这时就可以使用动态路由匹配。例如,要创建一个用户详情页面,每个用户有唯一的 ID,通过 ID 来展示对应用户的信息。定义动态路由的方式如下:
    // src/router/index.js
    import { createRouter, createWebHistory } from 'vue-router'
    // 导入路由对应的组件
    import Home from '../views/Home.vue'
    import About from '../views/About.vue'
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        component: About
      }
    ]
    
    const router = createRouter({
      history: createWebHistory(process.env.BASE_URL),
      routes
    })
    
    export default router

    上述代码中,createRouter用于创建路由实例,createWebHistory则用于启用 HTML5 History 模式,该模式下 URL 更加美观,没有#符号,但需要服务器进行相应配置,否则刷新页面可能出现 404 错误。若不想配置服务器,也可使用createWebHashHistory模式,即 Hash 模式,URL 会带有#符号,兼容性更好。routes数组定义了路由的映射关系,每个对象包含path(路径)、name(路由名称,方便通过名称进行导航)和component(路径对应的组件)。​

    (三)在 Vue 应用中使用路由​

    在main.js文件中引入并使用上述创建好的路由实例,代码如下:

    // src/main.js
    import { createApp } from 'vue'
    import App from './App.vue'
    import router from './router'
    
    createApp(App).use(router).mount('#app')

    通过app.use(router)将路由实例挂载到 Vue 应用中,这样整个应用就具备了路由功能。同时,在根组件App.vue中,需要使用<router - view>标签作为路由出口,用来渲染匹配到的组件。例如:

    <template>
      <div id="app">
        <router - view></router - view>
      </div>
    </template>

    二、路由配置详解​

    (一)路由模式​

    Vue Router 4 支持两种主要的路由模式:Hash 模式和 History 模式。​

  4. Hash 模式:使用 URL 的 hash(即#号后面的部分)来模拟一个完整的 URL,当#号后面的内容发生变化时,不会向服务器发送请求。这种模式兼容性好,在一些不支持 HTML5 History API 的老旧浏览器中也能正常使用。配置方式如下:
    const router = createRouter({
      history: createWebHashHistory(),
      routes: [...]
    })

    History 模式:利用 HTML5 History API 来实现 URL 的变化,通过pushState和replaceState方法改变浏览器地址栏的 URL,同时不会重新加载页面。这种模式下的 URL 更加简洁美观,符合现代 Web 应用的需求,但如前文所述,需要服务器进行配置,确保所有路径都能正确回退到index.html。配置代码如下:

    const router = createRouter({
      history: createWebHistory(),
      routes: [...]
    })
    (二)路由匹配​
  5. 动态路由匹配:在实际应用中,经常需要根据不同的参数来展示不同的内容,这时就可以使用动态路由匹配。例如,要创建一个用户详情页面,每个用户有唯一的 ID,通过 ID 来展示对应用户的信息。定义动态路由的方式如下:
    const routes = [
      {
        path: '/user/:id',
        component: User
      }
    ]

    在User组件中,可以通过$route.params.id来访问这个动态参数id。例如,在User组件的setup函数中获取参数:

    import { useRoute } from 'vue - router'
    export default {
      setup() {
        const route = useRoute()
        const userId = route.params.id
        // 可以根据userId进行数据请求等操作
        return {
          userId
        }
      }
    }

    路由参数的可选性:有时候,某个动态参数可能是可选的。例如,我们有一个商品详情页面,除了商品 ID 外,还可能有一个查询参数variant用于指定商品的变体。可以这样定义路由:

    const routes = [
      {
        path: '/product/:id',
        name: 'product',
        component: Product,
        children: [
          {
            path: 'variant',
            name: 'variant',
            component: Variant
          }
        ]
      }
    ]

    在Product组件中,可以通过$route.params.id获取商品 ID,通过$route.query.variant获取变体参数。当访问/product/123时,$route.query.variant为空;当访问/product/123?variant=red时,$route.query.variant的值为red。​

    (三)嵌套路由​

    在复杂的应用中,页面往往具有多层嵌套结构,Vue Router 允许配置嵌套路由来满足这种需求。例如,有一个用户管理模块,用户详情页面包含个人资料和用户发布的文章两个子页面。配置嵌套路由的代码如下:

    const routes = [
      {
        path: '/user/:id',
        component: User,
        children: [
          {
            path: 'profile',
            name: 'profile',
            component: UserProfile
          },
          {
            path: 'posts',
            name: 'posts',
            component: UserPosts
          }
        ]
      }
    ]

    在上述代码中,User组件作为父组件,其模板中需要包含<router - view>标签,用于渲染子路由对应的组件。例如:

    <template>
      <div>
        <h1>用户详情</h1>
        <router - view></router - view>
      </div>
    </template>

    当访问/user/123/profile时,UserProfile组件会被渲染到User组件的<router - view>中;当访问/user/123/posts时,UserPosts组件会被渲染。需要注意的是,子路由的path不需要以/开头,它会继承父路由的路径。​

    三、编程式导航​

    除了使用<router - link>组件进行声明式导航外,Vue Router 还提供了编程式导航的方式,即通过调用路由实例的方法来实现页面跳转。​

    (一)使用 push 方法​

    push方法用于向历史记录中添加一个新的路由记录,从而实现页面跳转。它可以接收多种类型的参数:​

  6. 字符串路径:直接传入目标路径字符串,例如:
    router.push('/home')

    带有路径的对象:通过对象形式传入路径,这种方式更加灵活,例如:

    router.push({ path: '/about' })

    命名的路由,并加上参数:如果在定义路由时给路由设置了name,可以通过name来导航,并传入参数,代码如下:

    router.push({ name: 'user', params: { id: 123 } })

    上述代码会跳转到name为user的路由,并将id参数设置为123。​

    4. 带查询参数:可以在跳转时携带查询参数,例如:

    router.push({ path: '/search', query: { keyword: 'vue' } })

    此时,跳转到的 URL 为/search?keyword=vue。​

    (二)使用 replace 方法​

    replace方法与push方法类似,不同之处在于replace方法不会向历史记录中添加新记录,而是替换当前的历史记录。例如:

    router.replace({ path: '/login' })

    执行上述代码后,当前页面会跳转到/login,并且历史记录中当前页面的记录会被/login的记录替换,用户无法通过浏览器的后退按钮回到之前的页面。​

    (三)使用 go 方法​

    go方法用于在历史记录中向前或向后跳转指定的步数,类似于浏览器的前进和后退按钮。例如

    //向前一页跳转
    router.go(1)
    //向后一页跳转
    router.go(-1)

    四、路由守卫​

    路由守卫主要用于通过跳转或取消的方式守卫导航,在路由导航的不同阶段执行特定的逻辑,例如权限验证、页面加载前的数据预取等。​

    (一)全局前置守卫​

    全局前置守卫会在每次路由导航之前被调用,其语法如下:

    router.beforeEach((to, from) => {
      // to: 即将进入的目标路由对象
      // from: 当前导航正要离开的路由对象
      // 可以在这里进行权限验证等操作
      if (to.meta.requiresAuth &&!isAuthenticated()) {
        return { name: 'login' } // 未登录则跳转到登录页面
      }
      return true // 允许导航
    })

    在上述代码中,to.meta.requiresAuth用于判断目标路由是否需要登录权限,isAuthenticated()是一个自定义函数,用于判断用户是否已经登录。如果用户未登录且目标路由需要权限,则返回一个新的路由对象,跳转到登录页面;否则返回true,允许导航继续进行。​

    (二)路由独享的守卫​

    每个路由配置对象可以定义自己的beforeEnter守卫,该守卫仅在进入该路由时被调用。例如:

    const routes = [
      {
        path: '/admin',
        name: 'admin',
        component: Admin,
        beforeEnter: (to, from) => {
          if (!isAdmin()) {
            return { name: 'home' } // 非管理员用户跳转到首页
          }
          return true
        }
      }
    ]

    这里的isAdmin()是一个判断用户是否为管理员的自定义函数,如果用户不是管理员,则跳转到首页,否则允许进入/admin路由。​

    (三)组件内的守卫​

    在组件内部也可以定义路由守卫,有以下几种:​

  7. beforeRouteEnter:在渲染该组件的对应路由被验证前调用,此时组件实例还未被创建,不能使用this。例如:
    export default {
      setup() {
        const beforeRouteEnter = (to, from) => {
          // 可以在进入路由前进行一些操作,如数据预取
          const userId = to.params.id
          fetchUserData(userId)
        }
        return {
          beforeRouteEnter
        }
      }
    }

    beforeRouteUpdate:在当前路由改变,但是该组件被复用时调用,例如,在动态路由参数变化时,组件不会重新创建,而是复用已有的组件实例,此时可以在这个守卫中处理参数变化的逻辑。代码如下:

    export default {
      setup() {
        const beforeRouteUpdate = (to, from) => {
          const newId = to.params.id
          const oldId = from.params.id
          if (newId!== oldId) {
            // 根据新的参数重新获取数据
            fetchData(newId)
          }
        }
        return {
          beforeRouteUpdate
        }
      }
    }

    beforeRouteLeave:在导航离开渲染该组件的对应路由时调用,可以用于防止用户不小心离开页面,例如,当用户在表单中输入了未保存的数据时,提示用户是否保存。示例代码如下:

    <template>
      <form>
        <input v - model="formData.name">
        <input v - model="formData.email">
      </form>
    </template>
    <script>
    export default {
      data() {
        return {
          formData: {
            name: '',
            email: ''
          }
        }
      },
      setup() {
        const beforeRouteLeave = (to, from) => {
          if (Object.keys(this.formData).some(key => this.formData[key])) {
            const confirmLeave = window.confirm('您有未保存的数据,确定离开吗?')
            return confirmLeave
          }
          return true
        }
        return {
          beforeRouteLeave
        }
      }
    }
    </script>

    五、路由元信息​

    在定义路由时,可以为每个路由配置meta字段,用于存储一些自定义的元信息,例如页面标题、是否需要权限等。这些元信息可以在路由守卫或组件中获取和使用。例如:

    const routes = [
      {
        path: '/dashboard',
        name: 'dashboard',
        component: Dashboard,
        meta: {
          title: '仪表盘',
          requiresAuth: true
        }
      },
      {
        path: '/login',
        name: 'login',
        component: Login,
        meta: {
          title: '登录'
        }
      }
    ]

    在全局前置守卫中,可以根据meta字段来设置页面标题,例如:​

    router.beforeEach((to, from) => {​
    
    document.title = to.meta.title || '默认标题'​
    
    return true​
    
    })​
    
    ​

    在权限验证时,也可以通过meta字段判断目标路由是否需要权限:​

    router.beforeEach((to, from) => {​
    
    if (to.meta.requiresAuth &&!isAuthenticated()) {​
    
    return { name: 'login' }​
    
    }​
    
    return true​
    
    })​
    
    ​

    通过以上对 Vue 3 路由配置和使用的详细讲解,相信你对 Vue Router 有了更深入的理解。合理运用路由的各种特性,可以构建出更加灵活、高效的单页应用。在实际开发中,根据项目需求不断探索和实践,充分发挥 Vue Router 的强大功能。

希望这篇博客能对你有所帮助,感兴趣的话,请在评论区留言讨论吧!!


网站公告

今日签到

点亮在社区的每一天
去签到