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

一、vue router基础配置,从0到1搭路由骨架

terry 23小时前 阅读数 20 #Vue

p标签开头:“不少刚接触Vue.js的同学,一碰到vue - router配置就犯难:路由咋设置?页面咋跳转?碰到动态路由、嵌套路由更是一头雾水,今天咱就把vue - router配置拆成基础、场景、进阶三个层面,用大白话讲清楚配置逻辑,新手也能跟着一步步做~”

先装依赖,项目里咋引入vue - router?
要是Vue2项目,先通过npm安装:npm install vue - router@3(Vue3对应@4版本),装完后,得在项目里新建路由文件,比如src/router/index.js,文件里要做这几步:

  • 导入Vue和VueRouter(Vue2用Vue.use(VueRouter),Vue3是createRoutercreateWebHistory这类API);
  • 定义路由规则数组,每个规则是{path: '/路径', component: 对应组件}
  • 创建路由实例,配置模式(比如history模式去掉#);
  • 导出实例,最后在main.js里把路由实例注入Vue根实例。
    举个Vue2的简单例子:
    // src/router/index.js
    import Vue from 'vue'
    import VueRouter from 'vue - router'
    import Home from '@/views/Home.vue'
    import About from '@/views/About.vue'

Vue.use(VueRouter) // 注册插件

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

const router = new VueRouter({ mode: 'history', // 选history模式,地址栏没#;hash模式有# routes })

export default router

然后在main.js里引入:  
```js
import Vue from 'vue'
import App from './App.vue'
import router from './router' // 引入路由实例
new Vue({
  router, // 注入路由
  render: h => h(App)
}).$mount('#app')

最后在App.vue里加<router - view>(显示匹配组件)和<router - link>(跳转用,替代a标签):

<template>
  <div id="app">
    <router - link to="/">首页</router - link>
    <router - link to="/about">lt;/router - link>
    <router - view></router - view>
  </div>
</template>

路由模式选history还是hash?有啥区别?
简单说,hash模式地址栏带(比如http://xxx/#/about),history模式没(http://xxx/about)。

  • hash模式:靠URL里的hash值(#后面部分)变化触发路由,兼容性好,不用后端配合;但地址栏有#,不太美观。
  • history模式:用HTML5的history API(pushState、replaceState),地址更干净,但部署时得让后端配合——所有前端路由对应的404请求,都重定向到index.html,否则刷新会报404,如果是本地开发或简单项目,hash模式够稳;想地址好看,正式项目部署前得和后端约定好重定向规则。

常见场景配置:动态路由、嵌套路由、编程式导航

动态路由咋配?比如商品详情页要传ID
当页面结构一样,数据不同(像商品详情、用户详情),就用动态路由,配置时,在path里加:参数名,组件里用$route.params拿参数。
步骤:

  • 路由规则里定义动态段:
    {
    path: '/product/:id', // :id是动态参数
    name: 'ProductDetail',
    component: ProductDetail
    }
  • 组件里接收参数:
    <template>
    <div>商品ID:{{ $route.params.id }}</div>
    </template>
    <script>
    export default {
    mounted() {
      console.log(this.$route.params.id) // 打印路由参数
    }
    }
    </script>
  • 跳转时,<router - link :to="{ name: 'ProductDetail', params: { id: 123 }}">商品123</router - link>,或者编程式导航this.$router.push({ name: 'ProductDetail', params: { id: 123 }})

嵌套路由咋实现?比如后台管理页有侧边栏+内容区
嵌套路由就是“路由里套路由”,父组件里有<router - view>显示子路由组件,配置时用children数组。
举个后台管理的例子:

  • 父组件Layout.vue结构:
    <template>
    <div>
      <aside>侧边栏</aside>
      <main>
        <router - view></router - view> <!-- 显示子路由组件 -->
      </main>
    </div>
    </template>
  • 路由规则里配置children:
    {
    path: '/admin',
    component: Layout,
    children: [
      {
        path: 'dashboard', // 注意:子路由path不加/,最终路径是/admin/dashboard
        name: 'Dashboard',
        component: Dashboard
      },
      {
        path: 'settings',
        name: 'Settings',
        component: Settings
      }
    ]
    }

    这样访问/admin/dashboard时,Layout组件渲染,同时Dashboard组件渲染到Layout里的<router - view>

编程式导航和<router - link>有啥区别?啥时候用this.$router.push?
<router - link>是声明式导航,适合模板里写跳转(比如导航栏按钮),编程式导航用this.$router.push/replace/go这些方法,适合逻辑里触发跳转(比如点击按钮后判断权限再跳转)。
比如登录成功后跳转:

<template>
  <button @click="handleLogin">登录</button>
</template>
<script>
export default {
  methods: {
    handleLogin() {
      // 登录逻辑...
      this.$router.push('/home') // 编程式导航跳转
    }
  }
}
</script>

push是添加新历史记录,replace是替换当前记录(后退时不会回到上一个页面),go(n)是前进或后退n步(类似浏览器history.go)。

进阶优化:路由守卫、懒加载、错误处理

路由守卫是干啥的?全局守卫和组件内守卫咋用?
路由守卫就是“路由跳转前/后做些操作”,比如权限判断、加载动画、埋点,分全局、路由独享、组件内三种。

  • 全局守卫:
    router.beforeEach((to, from, next) => {}) 跳转前触发,要调用next()放行/阻止,比如判断是否登录:

    // src/router/index.js
    router.beforeEach((to, from, next) => {
      const isLogin = localStorage.getItem('token')
      if (to.path === '/login' || isLogin) {
        next() // 登录页或已登录,放行
      } else {
        next('/login') // 没登录,跳登录页
      }
    })

    router.afterEach((to, from) => {}) 跳转后触发,不用next,适合做页面标题修改、埋点。

  • 组件内守卫:
    写在组件的js里,比如beforeRouteEnter(进入前,组件实例还没创建,不能用this)、beforeRouteUpdate(路由参数变化时,比如从/product/1到/product/2)、beforeRouteLeave(离开前,比如提醒用户保存):

    <script>
    export default {
      beforeRouteEnter(to, from, next) {
        // 组件还没创建,this是undefined
        next(vm => { // vm是组件实例
          vm.fetchData() // 可以调组件方法
        })
      },
      beforeRouteUpdate(to, from, next) {
        // 路由参数变了,product/:id,id从1变2
        this.id = to.params.id
        this.fetchData()
        next()
      },
      beforeRouteLeave(to, from, next) {
        if (this.formDirty) {
          if (window.confirm('有未保存内容,确定离开?')) {
            next()
          } else {
            next(false) // 阻止跳转
          }
        } else {
          next()
        }
      }
    }
    </script>

路由懒加载咋配?能优化首屏加载速度?
路由懒加载就是“用到哪个组件,再加载哪个组件”,减少首屏打包体积,配置时用动态import()语法。
原来的静态导入是import Home from '@/views/Home.vue',改成懒加载:

const Home = () => import('@/views/Home.vue')
const About = () => import('@/views/About.vue')
const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

这样每个组件会被打包成单独的chunk,访问对应路由时才加载,首屏加载更快,还能给懒加载加loading效果,

const Home = () => import(/* webpackChunkName: "home" */ '@/views/Home.vue')

webpack会给这个chunk命名,方便调试。

路由错误咋处理?比如404页面
配置一个通配符路由(或Vue3里的:pathMatch(.*)*),放在路由规则最后(因为路由匹配是从上到下,先匹配先渲染):
Vue2版本:

{
  path: '*', // 匹配所有未定义的路径
  component: Error404
}

Vue3版本(因为Vue3的路由更严格,要写:pathMatch(.*)*):

{
  path: '/:pathMatch(.*)*',
  name: 'NotFound',
  component: Error404
}

这样用户访问不存在的路由时,就会跳转到404页面。

避坑指南:这些配置细节新手常踩雷

路由跳转后,页面不更新是咋回事?
比如动态路由/product/:id,从/product/1跳到/product/2,组件复用了,生命周期钩子不会重新触发,解决方法:

  • 用组件内守卫beforeRouteUpdate,监听参数变化后重新请求数据;
  • <router - view>加key,强制组件重新渲染:<router - view :key="$route.fullPath"></router - view>(但可能影响性能,谨慎用)。

路由传参用query还是params?有啥区别?

  • params传参:参数在路由路径里(如/product/1),配置动态路由path: '/product/:id';刷新页面参数还在(因为在URL里),但如果路由没配动态段,params会丢失。
  • query传参:参数在URL的查询字符串里(如/product?id=1),路由不用配动态段,跳转时to: { path: '/product', query: { id: 1 }};刷新页面参数还在,适合非必填、可选的参数。
    简单说,想参数在URL里显示且刷新不丢,用query;想路径更干净(参数不在查询串),用params但要配动态路由。

嵌套路由的path为啥不能加斜杠?
嵌套路由的子路由path如果加,会变成根路径,比如父路由是/admin,子路由path写/dashboard,最终路径是/dashboard,而不是/admin/dashboard,所以子路由path要省略开头的,让它基于父路由路径拼接。

p标签结尾:“把vue - router配置拆成基础规则、场景方案、进阶优化这几块后,是不是清晰多了?其实核心就是「定义路由规则→注入Vue→用router - view和router - link渲染跳转」,再结合动态路由、嵌套、守卫这些功能,就能cover绝大多数项目场景,新手刚开始可以先把基础流程走通,再慢慢加场景化配置,碰到问题先看路由匹配顺序、参数传递方式这些细节,踩几次坑就熟啦~要是还有具体场景搞不定,评论区随时喊我分析~”

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门