router-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 Vue
的 router
选项:
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 怎么给组件传参?
传参分三种常见方式,场景不同选不同方法:
-
动态路由传参(适合参数是路径的一部分,比如文章 ID)
配置路由时,path
里用 占位符,{ path: '/article/:id', component: Article }
在 Article 组件里,用
this.$route.params.id
就能拿到参数(比如访问/article/123
,$route.params.id
'123'
)。 -
查询参数(类似 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
获取参数。 -
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>
但有时候不想缓存所有组件,这时候可以用 include
或 exclude
属性,比如只缓存 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 开发时常见坑有哪些?咋解决?
碰到的问题不少,挑几个高频的讲:
-
路由配置了但 router-view 不渲染组件
→ 先检查路由实例有没有挂载到 Vue 根实例(main.js
里的new Vue
有没有传router
);再看路由的path
和component
对应是否正确(component 路径写错,或者用了懒加载但语法错了);最后确认访问的 URL 和路由path
匹配(比如路由是/about
,访问的是/about/
会不匹配,除非配置了redirect
)。 -
嵌套路由的子组件不显示
→ 先看父路由组件的模板里有没有放<router-view>
(子路由必须有父组件里的 router-view 当出口);再检查子路由的path
配置,嵌套路由的子path
不用加 (比如父path
是/dashboard
,子path
写analysis
,完整路径是/dashboard/analysis
);还要确认父路由的component
有没有正确引入和注册。 -
用 keep-alive 缓存后,组件数据不更新
→ 因为组件实例被缓存了,mounted
不会再执行,解决方法有两种:一是把数据获取、更新的逻辑放到activated
钩子(每次激活组件时执行);二是给 router-view 加key
属性,让缓存失效(<router-view :key="$route.fullPath"></router-view>
,路径变化时强制重新渲染)。 -
页面里有多个 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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。