Code前端首页关于Code前端联系我们

一、vue router3是干啥的?项目里必须用它吗?

terry 3周前 (09-07) 阅读数 41 #Vue

想在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)。 装完后,得做这几步配置:

  1. 新建路由文件:一般在src下建个router文件夹,里面放index.js。
  2. 导入核心模块:在index.js里写:
    import Vue from 'vue'
    import VueRouter from 'vue-router'
    Vue.use(VueRouter) // 注册插件,让Vue能识别路由功能
    
  3. 定义路由规则:搞个routes数组,每个对象代表一条路由,
    const routes = [  
      {  
        path: '/', // 路径  
        name: 'Home', // 路由名(可选,方便编程式导航)  
        component: () => import('@/views/Home.vue') // 对应组件,用懒加载减少首屏体积  
      },  
      {  
        path: '/about',  
        name: 'About',  
        component: () => import('@/views/About.vue')  
      }  
    ]  
    
  4. 创建路由实例:
    const router = new VueRouter({  
      mode: 'history', // 路由模式,history是正常路径(/about),hash是带#的(/#/about)  
      routes // 上面定义的规则  
    })  
    
  5. 注入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配置~

步骤分三步:

  1. 定义父路由和子路由规则: 在routes数组里,给父路由加children属性(也是个数组):
    {  
      path: '/admin',  
      component: AdminLayout, // 父组件,里面得有放子路由  
      children: [  
        {  
          path: 'dashboard', // 注意!子路由path不加/,会自动拼接成/admin/dashboard  
          component: Dashboard  
        },  
        {  
          path: 'settings',  
          component: Settings  
        }  
      ]  
    }  
    
  2. 父组件里放: 比如AdminLayout.vue里得有:
      
    
  3. 跳转子路由: 可以用仪表盘,或者编程式this.$router.push('/admin/settings')

嵌套路由的核心是「父组件提供容器,子路由规则挂在children里」,实际开发中,像页面布局、多级菜单这些场景都得靠它拆分结构,让代码更模块化~

动态路由咋处理参数?组件复用的坑咋解决?

动态路由就是路径里带可变参数,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这些生命周期钩子不会再执行!导致参数变化后,页面数据没更新。

解决方法有两种:

  1. 用watch监听$route变化:
    watch: {  
      '$route' (to, from) {  
        // to是目标路由,from是来源路由  
        this.getArticleData(to.params.id) // 重新请求数据  
      }  
    }  
    
  2. 用组件内路由守卫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(文章详情,拿动态参数):

  
  

▎步骤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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门