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

router-view 到底是什么?

terry 2天前 阅读数 19 #Vue
文章标签 view;路由视图

p>Vue2 项目里的 router-view 是干啥用的?怎么在实际开发中配置、嵌套,碰到传参、缓存这类需求咋处理?不少刚入门 Vue2 的小伙伴对 router-view 又好奇又有点慌,这篇文章用问答形式把 router-view 的核心逻辑、实操方法和避坑要点掰碎了讲,帮你彻底搞透这个 Vue Router 里的关键角色~

简单说,router-view 是 Vue Router 提供的「路由出口」组件,你可以把它想象成一个「动态容器」—— 当浏览器地址栏的路径变化时,Vue Router 会找到匹配的路由规则,把对应的组件渲染到 router-view 所在的位置,比如做单页应用(SPA)时,页面整体结构(导航栏、页脚)不变,只有中间内容随路由切换,这时候 router-view 就是放「变化内容」的地方,不用每次切换都刷新整个页面,体验更流畅~

router-view 最基础的用法是怎样的?

想用 router-view,得先把 Vue Router 配置好,分三步走:

第一步:定义路由规则,在项目的 router 文件夹(一般是 src/router/index.js)里,创建路由实例时配置 routes 数组,比如做个首页和关于页的路由:

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/components/Home'
import About from '@/components/About'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/', // 访问根路径
      component: Home // 渲染 Home 组件
    },
    {
      path: '/about',
      component: About
    }
  ]
})

第二步:把 router 挂载到 Vue 根实例,在 main.js 里引入路由实例,传给 new Vuerouter 选项:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
new Vue({
  router, // 挂载路由
  render: h => h(App)
}).$mount('#app')

第三步:在页面模板里放 router-view,一般在 App.vue(整个应用的根组件)里,把 router-view 当容器:

<template>
  <div id="app">
    <header>导航栏</header>
    <router-view></router-view> <!-- 路由匹配的组件会渲染到这 -->
    <footer>页脚</footer>
  </div>
</template>

这样,访问 http://localhost:8080/ 时,Home 组件会显示在 router-view 位置;访问 /about 时,About 组件替换进来,导航和页脚保持不变~

router-view 怎么实现嵌套路由?

嵌套路由就是「路由里套路由」,适合页面有层级结构的场景,比如后台管理系统,/dashboard 是父页面(有侧边栏、顶栏),点侧边栏不同菜单,中间内容切换成 /dashboard/analysis/dashboard/statistics 这些子页面,实现分两步:

先配置嵌套的路由规则,在 routes 数组里,给父路由加 children 属性(数组),子路由的 path 不用写全路径,父路由 path 会自动拼接。

routes: [
  {
    path: '/dashboard',
    component: Dashboard, // 父组件
    children: [
      {
        path: 'analysis', // 完整路径是 /dashboard/analysis
        component: Analysis
      },
      {
        path: 'statistics',
        component: Statistics
      }
    ]
  }
]

然后在父组件(Dashboard.vue)的模板里,再放一个 router-view,作为子路由的出口:

<template>
  <div class="dashboard">
    <aside>侧边栏</aside>
    <main>
      <router-view></router-view> <!-- 子路由组件渲染到这 -->
    </main>
  </div>
</template>

这样访问 /dashboard 时,Dashboard 组件渲染,同时它内部的 router-view 会渲染 children 里匹配的子组件(比如访问 /dashboard/analysis,Analysis 组件就显示在父组件的 router-view 里)~

router-view 怎么给组件传参?

传参分三种常见方式,场景不同选不同方法:

  1. 动态路由传参(适合参数是路径的一部分,比如文章 ID)
    配置路由时,path 里用 占位符,

    {
    path: '/article/:id',
    component: Article
    }

    在 Article 组件里,用 this.$route.params.id 就能拿到参数(比如访问 /article/123$route.params.id '123')。

  2. 查询参数(类似 URL 里的 ?xxx=yyy,适合非必填、可选的参数)
    不用改路由 path,跳转时带 query 参数,比如用 <router-link :to="{ path: '/search', query: { keyword: 'Vue' }}">搜索</router-link>,或者编程式导航 this.$router.push({ path: '/search', query: { keyword: 'Vue' } })
    在目标组件里,用 this.$route.query.keyword 获取参数。

  3. props 传参(让组件更“纯”,解耦路由和组件)
    路由配置里加 props: true,这样 $route.params 里的参数会自动传给组件的 props

    {
    path: '/user/:id',
    component: User,
    props: true // 开启 props 传参
    }

    User 组件里定义 props 接收:

    <template>
    <div>用户 ID:{{ id }}</div>
    </template>
    <script>
    export default {
    props: ['id'] // 接收路由传的 id 参数
    }
    </script>

    这样组件里直接用 props,不用依赖 $route,维护和测试更方便~

router-view 切换时组件被销毁,想缓存状态咋办?

这时候得结合 Vue 的 <keep-alive> 组件,keep-alive 能缓存组件实例,避免每次切换路由都重新创建组件(比如表单输入一半切走,切回来还能保留内容),用法很简单:把 router-view 包在 keep-alive 里:

<template>
  <div id="app">
    <keep-alive>
      <router-view></router-view>
    </keep-alive>
  </div>
</template>

但有时候不想缓存所有组件,这时候可以用 includeexclude 属性,比如只缓存 Home 和 About 组件:

<keep-alive include="Home,About">
  <router-view></router-view>
</keep-alive>

(注意 include 的值是组件的 name 选项,Home 和 About 组件要声明 name: 'Home'name: 'About'

组件被缓存后,mounted 钩子只会执行一次,之后切换路由时,激活组件会触发 activated 钩子,离开时触发 deactivated 钩子,如果需要每次进入都执行逻辑,就把代码放到 activated 里~

router-view 开发时常见坑有哪些?咋解决?

碰到的问题不少,挑几个高频的讲:

  1. 路由配置了但 router-view 不渲染组件
    → 先检查路由实例有没有挂载到 Vue 根实例(main.js 里的 new Vue 有没有传 router);再看路由的 pathcomponent 对应是否正确(component 路径写错,或者用了懒加载但语法错了);最后确认访问的 URL 和路由 path 匹配(比如路由是 /about,访问的是 /about/ 会不匹配,除非配置了 redirect)。

  2. 嵌套路由的子组件不显示
    → 先看父路由组件的模板里有没有放 <router-view>(子路由必须有父组件里的 router-view 当出口);再检查子路由的 path 配置,嵌套路由的子 path 不用加 (比如父 path/dashboard,子 pathanalysis,完整路径是 /dashboard/analysis);还要确认父路由的 component 有没有正确引入和注册。

  3. 用 keep-alive 缓存后,组件数据不更新
    → 因为组件实例被缓存了,mounted 不会再执行,解决方法有两种:一是把数据获取、更新的逻辑放到 activated 钩子(每次激活组件时执行);二是给 router-view 加 key 属性,让缓存失效(<router-view :key="$route.fullPath"></router-view>,路径变化时强制重新渲染)。

  4. 页面里有多个 router-view,怎么区分?
    → 给 router-view 加 name 属性,路由配置里用 components(注意 s)对应。

    {
    path: '/layout',
    components: {
     default: Main, // 对应 <router-view>(没写 name 默认是 default)
     sidebar: Sidebar // 对应 <router-view name="sidebar">
    }
    }

    模板里这样写:

    <router-view></router-view> <!-- 渲染 Main -->
    <router-view name="sidebar"></router-view> <!-- 渲染 Sidebar -->

    这样多个 router-view 就能各司其职啦~

router-view 是 Vue2 路由系统的「核心出口」,从基础渲染到嵌套、传参、缓存,每个环节都和它密切相关,把这些用法和坑摸透,Vue2 单页应用的路由逻辑就顺了,实际开发中多结合业务场景试试,比如做后台管理系统的嵌套布局、商品详情页的动态路由传参,练几遍就熟啦~

版权声明

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

发表评论:

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

热门