Vue Router路由

1、Vue Router 是什么?

Vue Router​ 是 Vue.js 的官方路由管理器,用于构建单页面应用(SPA - Single Page Application)。它让 Vue.js 应用能够实现:

  • 多页面效果(实际上只有一个 HTML 页面)
  • URL 地址变化时,页面内容动态更新
  • 浏览器的前进/后退功能
  • 页面导航和跳转

2、为什么需要 Vue Router?

传统网站 vs 单页面应用

传统多页面网站:

复制代码
用户点击链接 → 浏览器向服务器请求新页面 → 服务器返回完整HTML → 页面完全刷新

Vue 单页面应用(使用 Vue Router):

复制代码
用户点击链接 → Vue Router 拦截 → 动态加载对应组件 → 局部更新页面内容
没有页面刷新,体验更流畅

3、安装与基本配置

1、安装
html 复制代码
npm install vue-router --save-dev

如果在一个模块化工程中使用,必须通过Vue.use()显示声明路由功能

html 复制代码
import Vue from'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter);
2、基本配置 src目录下创建文件夹router,专门存放路由,router下新建index.js
javascript 复制代码
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'

// 1. 导入自定义的路由组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import User from '../views/User.vue'
import NotFound from '../views/NotFound.vue'

// 2. 定义路由
const routes = [
  {
    //路由路径
    path: '/',
    //路由名称
    name: 'Home',
    //跳转到的组件
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    component: About
  },
  {
    path: '/user/:id',
    name: 'User',
    component: User,
    props: true  // 将路由参数作为 props 传递
  },
  {
    path: '/:pathMatch(.*)*',  // 404 页面
    name: 'NotFound',
    component: NotFound
  }
]

// 3. 创建路由实例
const router = createRouter({
  // 使用 HTML5 历史模式
  history: createWebHistory(),
  // 使用 hash 模式
  // history: createWebHashHistory(),
  routes
})

export default router

在main.js文件中配置路由

javascript 复制代码
// main.js
import { createApp } from 'vue'
import App from './App.vue'
// 导入上边创建的路由配置目录
import router from './router'

const app = createApp(App)
//配置路由
app.use(router)
app.mount('#app')

4、在App.vue中路由的使用

javascript 复制代码
<template>
  <div id="app">
    <!-- 导航栏 -->
    <nav>
      <router-link to="/">首页</router-link> |
      <router-link to="/about">备注</router-link> |
      <router-link :to="{ name: 'User', params: { id: 123 }}">用户信息</router-link>
    </nav>
    
    <!-- 路由出口,展示路由组件的内容 -->
    <router-view v-slot="{ Component }">
      <!-- 路由过渡效果 -->
      <transition name="fade" mode="out-in">
        <component :is="Component" />
      </transition>
    </router-view>
    
    <!-- 命名视图 -->
    <router-view name="sidebar" />
  </div>
</template>

<style>
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

5、编程式导航

javascript 复制代码
<script setup>
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()

// 导航到不同页面
const goHome = () => {
  router.push('/')
  // 或
  // router.push({ path: '/' })
  // 或
  // router.push({ name: 'Home' })
}

const goAbout = () => {
  router.push('/about')
}

const goUser = (id) => {
  router.push({ 
    name: 'User', 
    params: { id },
    query: { tab: 'profile' }  // 添加查询参数
  })
}

// 替换当前路由(不记录历史)
const replaceRoute = () => {
  router.replace('/about')
}

// 前进/后退
const goBack = () => {
  router.go(-1)  // 后退一步
}

const goForward = () => {
  router.go(1)  // 前进一步
}

// 获取路由参数
const userId = route.params.id
const tab = route.query.tab

// 监听路由变化
import { watch } from 'vue'
watch(
  () => route.params.id,
  (newId) => {
    console.log('用户ID变化:', newId)
  }
)
</script>

6、嵌套路由

路由配置文件

javascript 复制代码
// router/index.js
const routes = [
  {
    path: '/user/:id',
    component: UserLayout,
    children: [
      {
        path: '',
        name: 'UserProfile',
        component: UserProfile
      },
      {
        path: 'posts',
        name: 'UserPosts',
        component: UserPosts
      },
      {
        path: 'settings',
        name: 'UserSettings',
        component: UserSettings
      }
    ]
  }
]

组件页面

javascript 复制代码
<!-- User.vue -->
<template>
  <div>
    <h2>用户页面</h2>
    <nav>
      <router-link :to="`/user/${$route.params.id}`">查看资料</router-link>
      <router-link :to="`/user/${$route.params.id}/posts`">检阅文章</router-link>
      <router-link :to="`/user/${$route.params.id}/settings`">系统设置</router-link>
    </nav>
    <router-view />
  </div>
</template>

7、路由守卫

1、全局守卫
javascript 复制代码
// router/index.js
router.beforeEach((to, from) => {
  // 返回 false 取消导航
  // 返回路径字符串重定向
  // 返回 undefined 或 true 继续导航
  console.log('从', from.path, '到', to.path)
  
  // 检查是否需要登录
  if (to.meta.requiresAuth && !isAuthenticated()) {
    return { 
      name: 'Login',
      query: { redirect: to.fullPath }
    }
  }
})

router.afterEach((to, from) => {
  // 导航完成后执行
  document.title = to.meta.title || '默认标题'
})
2、路由独享守卫
javascript 复制代码
{
  path: '/admin',
  component: Admin,
  meta: { requiresAuth: true },
  beforeEnter: (to, from) => {
    // 仅对该路由生效
    if (!isAdmin()) {
      return { name: 'Home' }
    }
  }
}
3、组件内守卫
javascript 复制代码
<script setup>
import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router'

// 离开守卫
onBeforeRouteLeave((to, from) => {
  if (hasUnsavedChanges) {
    return confirm('有未保存的更改,确定离开吗?')
  }
})

// 路由更新守卫
onBeforeRouteUpdate((to, from) => {
  // 重新获取数据
  fetchData(to.params.id)
})
</script>

8、路由元信息和懒加载

javascript 复制代码
const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue'),  // 懒加载
    meta: {
      title: '首页',
      requiresAuth: false
    }
  },
  {
    path: '/dashboard',
    name: 'Dashboard',
    component: () => import('../views/Dashboard.vue'),
    meta: {
      title: '数据',
      requiresAuth: true,
      roles: ['admin', 'editor']  // 权限控制
    }
  }
]

// 路由元信息的使用
router.beforeEach((to, from) => {
  if (to.meta.requiresAuth) {
    const user = getUserInfo()
    if (!user) {
      return { name: 'Login' }
    }
    
    if (to.meta.roles && !to.meta.roles.includes(user.role)) {
      return { name: 'Forbidden' }
    }
  }
})

9、滚动行为

javascript 复制代码
const router = createRouter({
  history: createWebHistory(),
  routes,
  scrollBehavior(to, from, savedPosition) {
    // 返回锚点位置
    if (to.hash) {
      return {
        el: to.hash,
        behavior: 'smooth'
      }
    }
    
    // 返回之前的位置
    if (savedPosition) {
      return savedPosition
    }
    
    // 默认滚动到顶部
    return { top: 0 }
  }
})

10、动态路由

javascript 复制代码
// 添加路由
router.addRoute({
  path: '/new-route',
  component: () => import('../views/NewRoute.vue')
})

// 删除路由
const removeRoute = router.addRoute({ /* ... */ })
removeRoute()  // 删除添加的路由

// 获取所有路由
const allRoutes = router.getRoutes()

// 动态路由权限控制
function setupRoutes(userRole) {
  const routes = [
    { path: '/', component: Home }
  ]
  
  if (userRole === 'admin') {
    routes.push({
      path: '/admin',
      component: () => import('../views/Admin.vue')
    })
  }
  
  // 重置路由
  router.removeRoute('admin')
  routes.forEach(route => {
    router.addRoute(route)
  })
}

11、补充

1、常用工具函数
javascript 复制代码
<script setup>
import { useRouter, useRoute } from 'vue-router'

const router = useRouter()
const route = useRoute()

// 判断当前路由
const isActive = (path) => {
  return route.path === path
}

// 获取完整路径
const fullPath = route.fullPath

// 获取查询参数
const queryParams = route.query

// 路由匹配
const matchedRoutes = route.matched
</script>
2、路由跳转时传递数据
javascript 复制代码
// 通过 query
router.push({
  path: '/user',
  query: { id: 123456, name: '张三' }
})

// 通过 params(需要命名路由)
router.push({
  name: 'User',
  params: { id: 123456, name: '张三' }
})

// 在组件中接收
const route = useRoute()
const id = route.params.id
const name = route.query.name
相关推荐
阿呜的边城2 小时前
终于还是吃上了react-i18next的细糠
前端·前端框架
米方2 小时前
ElementPlus 穿梭框支持批量穿梭
前端·javascript·vue.js
InkHeart2 小时前
uni-app开发路上的坑
前端·vue.js
用户4099322502122 小时前
Vue3中v-bind:class与v-bind:style如何实现条件样式、组件样式合并与深层响应式管理?
前端·ai编程·trae
还算善良_2 小时前
【Vue】表格实现表头多彩
javascript·vue.js·ecmascript
我是天龙_绍2 小时前
如何在前端开发中高效运用AI:从提效到避坑
前端
KenXu2 小时前
从Vue 到 React:Valtio 让状态管理更熟悉
前端
JS_GGbond2 小时前
用Canvas和SVG制作简单动画:从零开始的视觉魔法
javascript
努力学习的少女2 小时前
对SparkRDD的认识
开发语言·前端·javascript