当前位置: 首页 > java >正文

前端笔记-Vue router

学习目标

Vue Router路由管理1、路由配置
2、嵌套路由
3、路由守卫与权限控制

 

一、路由配置(给网站做地图)

npm i vue-router

作用​:告诉浏览器什么地址该显示什么页面
核心代码​:

// 创建路由并暴露出去// 第一步:引入createRouter方法
import { createRouter, createWebHashHistory} from 'vue-router'//引入一个个路由组件
import Home from '@/components/Home.vue'
import About from '@/components/About.vue'
import News from '@/components/News.vue'// 第二步:创建路由实例
const router = createRouter({history:createWebHashHistory(),routes:[{path:'/home',component:Home},{path:'/about',component:About},{path:'/news',component:News  }]
})// 暴露出去router
export default router

使用场景​:

  • 点击导航菜单切换页面
  • 直接输入网址访问特定页面

二、嵌套路由(套娃页面)

作用​:在页面内部再嵌套子页面(如后台s
示例​:

const routes = [{path: '/user',component: UserLayout, // 父组件(带公共布局)children: [            // 子路由列表{path: '',          // /usercomponent: UserHome},{path: 'profile',   // /user/profilecomponent: UserProfile}]}
]

三、路由守卫与权限控制(保安检查)

作用​:控制谁能进入页面(如登录验证)

1. 全局守卫(大门保安)​

router.beforeEach((to, from, next) => {if (to.path === '/admin' && !isLogin()) {next('/login') // 跳转到登录页} else {next() // 放行}
})

2. 路由独享守卫(房间保安)​

{path: '/dashboard',component: Dashboard,beforeEnter: (to, from, next) => {// 专门检查这个路由的权限}
}

3. 组件内守卫(内部监控)​

export default {beforeRouteEnter(to, from, next) {// 进入组件前调用},beforeRouteLeave(to, from, next) {// 离开组件时调用if (hasUnsavedChanges) {return confirm('确定离开吗?未保存的数据会丢失!')}}
}

四、路由系统三大核心要素

  1. 导航区​(控制中心)

    • 使用 <router-link> 组件代替传统 <a> 标签
    • 示例:
      <div class="nav"><router-link to="/">首页</router-link><router-link to="/about">关于</router-link>
      </div>
  2. 展示区​(动态画布)

    • 用 <router-view> 作为内容渲染出口
    • 示例:
      <div class="content"><router-view></router-view> <!-- 这里显示路由对应的组件 -->
      </div>
  3. 路由器​(指挥中心)

    • 创建步骤:
      // 1. 安装路由
      npm install vue-router@4// 2. 创建路由实例(router/index.js)
      import { createRouter, createWebHistory } from 'vue-router'const router = createRouter({history: createWebHistory(),routes: [] // 路由规则稍后添加
      })

五、路由规则配置(交通法规)

  1. 基本路由规则

    const routes = [{path: '/',          // 访问路径name: 'home',       // 路由名称(可选)component: Home     // 对应的组件},{path: '/about',component: () => import('@/views/About.vue') // 懒加载}
    ]
  2. 动态路由示例

    {path: '/user/:id',    // 动态参数component: UserDetail
    }

Vue Router 工作模式

两种模式对比
特性History 模式Hash 模式
URL美观度无#,美观 (e.g. /user/profile)带# (e.g. /#/user/profile)
服务器要求需要特殊配置无需特殊配置
SEO优化友好较差
兼容性现代浏览器所有浏览器
刷新行为需服务器支持,否则404正常加载
1. History 模式

原理​:基于HTML5 History API (pushStatereplaceState)

const router = createRouter({history: createWebHistory(),  // 使用history模式routes: [...]
})

特点​:

  • ✅ URL更简洁:https://example.com/user/profile
  • ✅ 对SEO更友好
  • ❌ 需要服务器配置:
    # Nginx示例配置
    location / {try_files $uri $uri/ /index.html;
    }

2. Hash 模式

原理​:基于URL hash (#)

const router = createRouter({history: createWebHashHistory(),  // 使用hash模式routes: [...]
})

特点​:

  • ✅ 开箱即用,无需服务器配置
  • ✅ 兼容IE9等老旧浏览器
  • ❌ URL包含#:https://example.com/#/user/profile
  • ❌ 服务端渲染(SSR)不支持
选择建议
  1. 开发环境​:两种模式均可,优先测试history模式
  2. 生产环境​:
    • 有服务器控制权 → 选择history模式
    • 静态网站托管(如GitHub Pages) → 选择hash模式
  3. SEO要求高​:必须使用history模式+SSR

Vue Router 传参

1. ​Query参数​(适合筛选/非必要参数)

News.vue

<template><div class="news"><!-- 导航区 --><ul><li v-for="(news,index) in newsList" :key="index"><RouterLink:to="{path:'news/detail',query:{id:index,title:news.title,date:news.date,category:news.category,brief:news.brief,author:news.author,content:news.content}}">{{ news.title }}</RouterLink></li></ul><!-- 新闻详情区 --><div class="news-container"><RouterView></RouterView></div></div>
</template>

特点​:

  • URL格式:/news/detail?id=0&from=news-list
  • 通过route.query.id获取
  • 适用场景​:分页、筛选等可选参数
  • 图片风格适配​:保持绿色按钮+深蓝激活态

对应Detail.vue

<template><div class="news-detail-container"><h3>{{query.title}}</h3><div class="news-detail-meta"><span>发布日期:{{ query.date }}</span><span>作者:{{ query.author }}</span><span>分类:{{ query.category }}</span></div><div class="news-detail-content"><p>{{ query.content }}</p></div></div>
</template><script lang="ts" setup>
import { toRefs} from 'vue'
import { useRoute } from 'vue-router'let route = useRoute()
let {query} = toRefs(route)</script>

2. ​Params参数​(适合必要参数)

上述同样的代码,我们换成params传参,需要注意的是,在router/index.ts文件路由路径中需要提前占位(即要传什么参数,先提前写好)

路由配置:router/index.ts

const routes: RouteRecordRaw[] = [{path: '/news',component: () => import('@/views/News.vue'),children: [{name: 'xiang', path: 'detail/:id/:title/:date/:author/:category/:content',component: () => import('@/views/Detail.vue')}]}
]

 News.vue

<template><div class="news"><!-- 导航区 --><ul><li v-for="(news,index) in newsList" :key="index"><RouterLink:to="{name: 'xiang', // 使用图片中的路由名称params: { id: index,title: news.title,date: news.date,author: news.author,category: news.category,content: news.content.join('|') // 将数组转换为字符串}}">{{ news.title }}</RouterLink></li></ul><!-- 新闻详情区 --><div class="news-container"><RouterView></RouterView></div></div>
</template>

Detail.vue

<template><div class="news-detail-container"><h3>{{ title }}</h3><div class="news-detail-meta"><span>发布日期: {{ date }}</span><span>作者: {{ author }}</span><span>分类: {{ category }}</span></div><div class="news-detail-content"><p v-for="(para, index) in parsedContent" :key="index">{{ para }}</p></div></div>
</template><script lang="ts" setup>
import { computed } from 'vue'const props = defineProps({id: String,title: String,date: String,author: String,category: String,content: String
})// 将字符串转换回数组
const parsedContent = computed(() => {return props.content?.split('|') || []
})
</script>

特点​:

  • URL格式:/news/detail/1
  • 通过route.params.id获取
  • 适用场景​:新闻ID等必要参数
  • 图片风格适配​:卡片内链接触发绿色悬停效果

3. ​路由的Props配置

路由配置:router/index.ts

const routes: RouteRecordRaw[] = [{path: '/news',component: () => import('@/views/News.vue'),children: [{name: 'xiang', path:'detail',component:Detail,props: (route) => route.query}]}
]

props还有其他几种写法

// props的对象写法,作用:把对象中的每一组key-value作为props传给Detail组件// props:{a:1,b:2,c:3}, // props的布尔值写法,作用:把收到了每一组params参数,作为props传给Detail组件// props:true// props的函数写法,作用:把返回的对象中每一组key-value作为props传给Detail组件props(route){return route.query}

 News.vue

<template><div class="news"><!-- 导航区 --><ul><li v-for="(news,index) in newsList" :key="index"><RouterLink:to="{path:'/news/detail',query: { // 直接传所有数据id: index,...news }}">{{ news.title }}</RouterLink></li></ul><!-- 新闻详情区 --><div class="news-container"><RouterView></RouterView></div></div>
</template>

Detail.vue

<template><div class="news-detail-container"><h3>{{title}}</h3><div class="news-detail-meta"><span>发布日期:{{ date }}</span><span>作者:{{author }}</span></div><div class="news-detail-content"><p>{{ content }}</p></div></div>
</template><script lang="ts" setup>defineProps(['id', 'title', 'date', 'author', 'content'])</script>

优势​:

  • 解耦组件和路由
  • 类型安全(TypeScript友好)

传参方式对比表格

方式URL示例获取方法适用场景图片UI对应位置
Query/news?id=1&from=listroute.query.id筛选、排序等可选参数左侧导航栏筛选按钮
Params/news/1route.params.id详情页ID等必要参数右侧新闻卡片跳转链接
Props/news/1组件props需要类型检查的场景内容区详情组件

补充:编程式路由导航

基础编程式导航

1. 路由跳转(替换当前历史记录)
import { useRouter } from 'vue-router'const router = useRouter()// 跳转到指定路径
router.push('/news') // 带参数跳转(匹配您的图片配置)
router.push({path: '/news/detail',query: { id: 1,title: 'Vue 3.4 发布',content: JSON.stringify(['内容1', '内容2'])}
})// 命名路由跳转(推荐)
router.push({name: 'xiang',params: { id: 1 },query: { title: 'Vue 3.4 发布' }
})
2. 路由替换(无历史记录)
router.replace('/about') // 替换当前条目
3. 历史记录控制
router.go(1)  // 前进
router.go(-1) // 后退
router.back() // 等价于 go(-1)

动态路由实践

1. 带参数的新闻跳转
// 在新闻列表中的点击事件
const gotoDetail = (news, index) => {router.push({path: '/news/detail',query: {id: index,...news,content: JSON.stringify(news.content) // 数组需序列化}})
}
2. 接收参数(两种方式)
// 方式1:通过 props 接收(推荐)
defineProps({id: [String, Number],title: String,content: String // 需自行反序列化
})// 方式2:通过路由实例
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.id) // 获取query参数

三、高级应用技巧

1. 路由守卫控制
router.beforeEach((to, from) => {if (to.path === '/news/detail' && !to.query.id) {return '/news' // 拦截无效访问}
})
2. 动态路由追加(根据权限)
router.addRoute({path: '/admin',component: () => import('@/views/Admin.vue')
})
3. 路由元信息(扩展功能)
// 路由配置中
meta: { requiresAuth: true }// 组件中获取
const route = useRoute()
console.log(route.meta.requiresAuth)

项目实践

1. 路由参数处理优化
// 在 detail.vue 中安全解析参数
const parsedContent = computed(() => {try {return JSON.parse(props.content || '[]')} catch {return ['无效内容格式']}
})
2. 类型安全(TypeScript)
interface NewsParams {id: string | numbertitle: stringcontent: string
}const props = defineProps<NewsParams>()
3. 导航失败处理
router.push('/news').catch(err => {console.error('导航失败:', err)
})

常见问题解决方案

1. 路由重复跳转报错
// 在 router/index.js 中
const router = createRouter({history: createWebHashHistory(),routes,strict: true // 严格模式
})
2. 刷新后参数丢失
// 使用 localStorage 做持久化
router.push({path: '/news/detail',query: {id: localStorage.getItem('lastNewsId') }
})
3. 滚动行为控制
const router = createRouter({scrollBehavior(to) {if (to.hash) {return { el: to.hash }}return { top: 0 }}
})

补充:路由重定向

基础重定向配置

const routes = [{path: '/',redirect: '/news' // 首页重定向到新闻页},{path: '/news',component: News,children: [{path: 'detail',redirect: { name: 'xiang', // 命名路由重定向query: { id: 0 } // 默认显示第一条新闻}}]}
]

动态重定向(适合新闻详情页)

1. 根据条件重定向
{path: '/old-news/:id',redirect: to => ({path: '/news/detail',query: { id: to.params.id } // 保持参数不变})
}
2. 404重定向
{path: '/:pathMatch(.*)*',redirect: '/news' // 所有未知路径跳转新闻首页
}

路由守卫重定向(权限控制)

router.beforeEach((to, from) => {// 模仿图片中的新闻详情页鉴权if (to.path === '/news/detail' && !to.query.id) {return { path: '/news',query: { redirect: to.fullPath } // 保存目标路径}}
})

视觉友好型重定向

1. 带过渡效果的重定向
router.afterEach((to, from) => {// 图片中的浅绿色进度条效果document.querySelector('.progress-bar').style.width = '100%'setTimeout(() => {document.querySelector('.progress-bar').style.width = '0'}, 500)
})
2. 重定向状态提示(类似图片中的发布日期样式)
<template><div v-if="isRedirecting" class="redirect-notice"><p>正在跳转到新闻页...</p><div class="loading-bar" style="background-color: #b6edd6;"></div></div>
</template>


组件文件结构示例

src/
├── router/
│   └── index.js          # 路由配置文件
├── views/                # 路由级组件
│   ├── Home.vue
│   ├── About.vue
│   └── News/
│       ├
│       └── Detail.vue
└── App.vue               # 根组件(包含router-view)

完整工作流程实战

  1. App.vue​(主框架)

    <template><div class="app"><h2 class="title">Vue路由测试</h2><!-- 导航区 --><div class="navigate"><RouterLink to="/home" active-class="active">首页</RouterLink><RouterLink to="/news" active-class="active">新闻</RouterLink><RouterLink to="/about" active-class="active">关于</RouterLink></div><!-- 展示区 --><div class="main-content"><RouterView></RouterView></div></div>
    </template><script lang="ts" setup name="App">import {RouterView,RouterLink} from 'vue-router'
    </script>
  2. 路由配置​(router/index.js)

    // 创建路由并暴露出去// 第一步:引入createRouter方法
    import { createRouter, createWebHashHistory} from 'vue-router'//引入一个个路由组件
    import Home from '@/views/Home.vue'
    import About from '@/views/About.vue'
    import News from '@/views/News.vue'// 第二步:创建路由实例
    const router = createRouter({history:createWebHashHistory(),routes:[{path:'/home',component:Home},{path:'/about',component:About},{path:'/news',component:News  }]
    })// 暴露出去router
    export default router
  3. 启动路由​(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')

 完整效果展示:

 

源代码路径: 

 

http://www.xdnf.cn/news/1527.html

相关文章:

  • 自主可控鸿道Intewell工业实时操作系统
  • 量子跃迁:Vue组件安全工程的基因重组与生态免疫(完全体)
  • Spring AI - Redis缓存对话
  • 第五章:5.3 ESP32物联网应用:阿里云IoT平台与腾讯云IoT平台的数据上传与远程控制
  • 阻塞式队列
  • 非关系型数据库 八股文 Redis相关 缓存雪崩 击穿 穿透
  • Vite/Rollup 模块热更新
  • Springboot整合Redis主从
  • Java基础系列-HashMap源码解析2-AVL树
  • Java内存模型之JMM
  • NEUOJ网格路径
  • 本地服务器 Odoo 安装指南,并实现公网访问
  • MySQL基础增删改
  • LeetCode-47. 全排列 II
  • 杰理ac792开发板按键不起效果
  • ElasticSearch:高并发场景下如何保证读写一致性?
  • 搭建TypeScript单元测试环境
  • 高性能全闪存储在大模型训练与推理中的效率提升作用
  • HTTP 请求头的 key 不区分大小写。
  • 接口测试和功能测试详解
  • 【AI】Windows环境安装SPAR3D单图三维重建心得
  • 玩转Docker | 使用Docker部署Neko自托管浏览器
  • Chronos - 时间序列预测语言模型
  • SwiftUI 1.Text介绍和使用
  • Elasticsearch 报错 Limit of total fields [1000] has been exceeded
  • SwiftUI 3.Button介绍和使用
  • Python爬虫学习:高校数据爬取与可视化
  • UIAutomator 与 Playwright 在 AI 自动化中的界面修改对比
  • Java学习手册:Web 安全基础
  • MyBatis 升级至 MyBatis-Plus 详细步骤