一、vue router3是干啥的?项目里必须用它吗?
想在Vue2项目里实现页面跳转不刷新、管理路由逻辑?vue - router3作为Vue2生态的核心路由工具,能帮我们搞定单页应用(SPA)的路由管理,但新手常犯愁:它咋安装配置?路由跳转、嵌套路由这些咋玩?碰到动态路由、权限拦截又咋处理?这篇从基础到实战,把vue - router3的关键知识点拆成问答,帮你一步一步吃透~
简单说,vue - router3是Vue2官方的路由管理器,专门解决单页应用的「页面」切换问题,咱做SPA时,整个项目就一个HTML页面,页面里的内容靠组件切换实现,vue - router3能帮咱:① 配置不同路径对应哪个组件;② 实现组件间跳转(还能控制浏览器历史记录);③ 处理多级路由、动态参数这些复杂场景… 要是项目就几个静态页面,不用路由也能写,但只要涉及「页面级别的组件切换」「需要前进后退」「带参数跳转」,vue - router3能让代码更规整,开发效率翻倍,比如做后台管理系统、博客、电商详情页这些场景,它就是刚需~
vue - router3咋安装?基础配置步骤是啥?
先装依赖,打开终端,在Vue2项目里执行:npm install vue - router@3
(指定版本3,因为vue - router4对应Vue3)。 装完后,得做这几步配置:
- 新建路由文件:一般在src下建个router文件夹,里面放index.js。
- 导入核心模块:在index.js里写:
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) // 注册插件,让Vue能识别路由功能
- 定义路由规则:搞个routes数组,每个对象代表一条路由,
const routes = [ { path: '/', // 路径 name: 'Home', // 路由名(可选,方便编程式导航) component: () => import('@/views/Home.vue') // 对应组件,用懒加载减少首屏体积 }, { path: '/about', name: 'About', component: () => import('@/views/About.vue') } ]
- 创建路由实例:
const router = new VueRouter({ mode: 'history', // 路由模式,history是正常路径(/about),hash是带#的(/#/about) routes // 上面定义的规则 })
- 注入Vue实例:在main.js里导入router,然后new Vue时加router选项:
import router from './router' new Vue({ router, // 注入后,所有组件能通过this.$router/this.$route访问路由 render: h => h(App) }).$mount('#app')
配置完,在App.vue里加
路由咋跳转?声明式和编程式有啥区别?
vue - router3提供两种跳转方式,场景不同选不同的:
▎声明式:用组件
写法像这样:
它的好处是「不用写JS逻辑」,适合导航栏、菜单这些静态跳转,还能加active - class属性,控制选中样式(默认是router - link - active)。 要是需要传参数,query传参可以这样:
跳转后路径是/article?id = 123,组件里用this.$route.query.id
拿参数。
▎编程式:用this.$router的方法
常见的有push、replace、go:
- push:跳转到新路由,会添加一条历史记录(能回退)
this.$router.push('/about')
// 直接写路径this.$router.push({ name: 'Article', params: { id: 123 } })
// 用路由名+params(得配合动态路由path: '/article/:id') - replace:跳转时替换当前历史记录,没法回退到上一个页面
this.$router.replace('/about')
- go:控制前进后退,类似history.go()
this.$router.go(-1)
// 后退一步this.$router.go(2)
// 前进两步
编程式适合「点击按钮触发逻辑后跳转」,比如表单提交成功后跳转到列表页,另外要注意:用params传参时,得配合路由规则里的动态参数(path: '/article/:id'),否则刷新页面参数会丢;query传参则不会,因为参数在URL上~
嵌套路由咋玩?多级页面结构咋拆?
嵌套路由就是「路由里套路由」,比如做后台管理系统,layouts页面里有侧边栏(SideBar)和主体内容(Main),主体内容要根据不同子路由切换(dashboard、/settings),这时候就得用children配置~
步骤分三步:
- 定义父路由和子路由规则: 在routes数组里,给父路由加children属性(也是个数组):
{ path: '/admin', component: AdminLayout, // 父组件,里面得有
放子路由 children: [ { path: 'dashboard', // 注意!子路由path不加/,会自动拼接成/admin/dashboard component: Dashboard }, { path: 'settings', component: Settings } ] } - 父组件里放
: 比如AdminLayout.vue里得有: - 跳转子路由: 可以用
,或者编程式仪表盘 this.$router.push('/admin/settings')
嵌套路由的核心是「父组件提供
动态路由咋处理参数?组件复用的坑咋解决?
动态路由就是路径里带可变参数,article/1、/article/2,共用同一个Article组件,配置时要在路由规则里加动态段:
{
path: '/article/:id', // :id是动态参数
name: 'Article',
component: Article
}
▎拿参数的两种方式:
- $route.params:组件里用
this.$route.params.id
拿到动态参数; - $route.query:如果是?id = 1这种查询参数,用
this.$route.query.id
。
▎组件复用的坑:
当从/article/1跳到/article/2时,Article组件会被复用(因为是同一个组件),这时候created、mounted这些生命周期钩子不会再执行!导致参数变化后,页面数据没更新。
解决方法有两种:
- 用watch监听$route变化:
watch: { '$route' (to, from) { // to是目标路由,from是来源路由 this.getArticleData(to.params.id) // 重新请求数据 } }
- 用组件内路由守卫beforeRouteUpdate:
beforeRouteUpdate(to, from, next) { this.id = to.params.id this.getArticleData(this.id) next() // 必须调用next()放行 }
动态路由在详情页、商品页这些场景常用,组件复用导致生命周期不触发」的坑,用watch或守卫解决就好~
路由守卫是干啥的?不同守卫咋用?
路由守卫就像「路由的门卫」,在路由跳转前、后做拦截或处理,比如登录验证、页面权限、数据预加载这些,vue - router3的守卫分三类:全局守卫、路由独享守卫、组件内守卫。
▎全局守卫(作用于所有路由)
- router.beforeEach:跳转前触发,常用作登录拦截 比如判断用户是否登录,没登录就跳转到登录页:
router.beforeEach((to, from, next) => { const isLogin = localStorage.getItem('token') if (to.meta.requiresAuth && !isLogin) { next('/login') // 没登录且需要权限,跳登录 } else { next() // 放行 } })
- router.afterEach:跳转后触发,常用作页面标题修改、埋点统计
router.afterEach((to, from) => { document.title = to.meta.title || '默认标题' })
▎路由独享守卫(只作用于某条路由)
在路由规则里写beforeEnter:
{
path: '/profile',
component: Profile,
meta: { requiresAuth: true },
beforeEnter: (to, from, next) => {
// 逻辑和beforeEach类似,只对当前路由生效
if (!isLogin()) {
next('/login')
} else {
next()
}
}
}
▎组件内守卫(作用于组件内)
- beforeRouteEnter:路由进入前触发(组件还没创建,this是undefined)
beforeRouteEnter(to, from, next) { // 可以在这里请求数据,传给组件实例 next(vm => { // vm是组件实例,创建后执行 vm.getData() }) }
- beforeRouteUpdate:路由更新时触发(比如动态路由参数变化,组件复用) 前面动态路由部分讲过,用来处理参数变化后的数据更新。
- beforeRouteLeave:路由离开前触发,常用作提示用户保存
beforeRouteLeave(to, from, next) { if (this.formEdited) { if (window.confirm('表单没保存,确定离开?')) { next() } else { next(false) // 取消跳转 } } else { next() } }
守卫的核心是「控制路由跳转的流程」,登录拦截、权限管理、数据预加载这些场景都离不开它,要注意守卫的执行顺序:全局beforeEach → 路由独享beforeEnter → 组件内beforeRouteEnter → 组件内beforeRouteUpdate(如果是更新) → 全局afterEach~
实战:用vue - router3搭个简易博客系统
光讲理论不够,咱动手搭个能「看首页、列表、详情、的博客,把前面知识点串起来~
▎步骤1:初始化Vue2项目
用vue - cli创建项目:vue create blog - demo
,选Vue2的配置。
▎步骤2:安装vue - router3
cd blog - demo → npm install vue - router@3
▎步骤3:配置路由规则(src/router/index.js)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 懒加载导入组件
const Home = () => import('@/views/Home.vue')
const ArticleList = () => import('@/views/ArticleList.vue')
const ArticleDetail = () => import('@/views/ArticleDetail.vue')
const About = () => import('@/views/About.vue')
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/articles',
name: 'ArticleList',
component: ArticleList
},
{
path: '/article/:id', // 动态路由,id是文章id
name: 'ArticleDetail',
component: ArticleDetail
},
{
path: '/about',
name: 'About',
component: About
}
]
const router = new VueRouter({
mode: 'history',
routes
})
export default router
▎步骤4:写组件(以ArticleList和ArticleDetail为例)
- ArticleList.vue(文章列表,模拟数据):
去关于页
- ArticleDetail.vue(文章详情,拿动态参数):
文章ID:{{ $route.params.id }}
这里是文章内容...
▎步骤5:全局守卫做登录拦截(模拟)
在router/index.js里加:
router.beforeEach((to, from, next) => {
// 模拟是否登录(实际项目从localStorage或Vuex取)
const isLogin = false // 假设没登录
// 给需要权限的路由加meta.requiresAuth
if (to.meta.requiresAuth && !isLogin) {
next('/') // 没登录就跳首页
} else {
next()
}
})
然后给需要权限的路由加meta,
{
path: '/article/:id',
name: 'ArticleDetail',
component: ArticleDetail,
meta: { requiresAuth: true } // 假设详情页需要登录
}
▎步骤6:测试功能
启动项目:npm run serve
,访问localhost:8080,试试:
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。