Vue.js里的router-view到底怎么用?常见问题一次讲清
做Vue项目时,路由跳转和页面渲染是绕不开的环节,而router-view作为Vue Router的核心组件,好多同学刚接触时总会犯懵:它到底是干啥的?怎么用才顺手?嵌套、传参、缓存这些需求咋实现?今天咱们就把router-view的常见问题掰碎了讲,从基础到进阶一次搞懂~
router-view是啥?在Vue路由里扮演啥角色?
简单说,router-view是Vue Router提供的「占位组件」,咱做单页应用(SPA)时,页面切换不需要整页刷新,而是动态替换页面里的某块内容,router-view就是专门用来“占住这块位置”,让匹配到的路由组件在这显示的。
举个例子:做个博客系统,有首页、文章列表、文章详情页,这时候把<router-view>
放在App.vue里,访问首页时,它渲染Home组件;点文章列表,就替换成ArticleList组件;点具体文章,又变成ArticleDetail组件,所以router-view是「路由系统和页面渲染的桥梁」——路由规则匹配到哪个组件,它就把那个组件“吐”在自己的位置上。
咋在项目里引入和使用router-view?
想用router-view,得先把Vue Router整好,步骤分这几步:
① 安装Vue Router
如果是Vue2,执行 npm i vue-router@3
;Vue3则用 npm i vue-router@4
。
② 配置路由规则
新建个router
文件夹,里面建index.js
(以Vue2为例):
import Vue from 'vue' import VueRouter from 'vue-router' import Home from '@/views/Home.vue' import About from '@/views/About.vue' Vue.use(VueRouter) // 注册Vue Router插件 const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ] const router = new VueRouter({ routes }) export default router
③ 在根组件里用router-view
以App.vue为例,把<router-view>
当“容器”用:
<template> <div id="app"> <!-- 导航用router-link --> <router-link to="/">首页</router-link> <router-link to="/about">lt;/router-link> <!-- 渲染路由组件的位置 --> <router-view></router-view> </div> </template>
这样一配置,访问不同路径时,router-view就会自动把对应的Home、About组件渲染出来,要是做嵌套路由(比如页面里还有子页面),接着看下面~
嵌套路由里的router-view咋玩?
嵌套路由就是“路由里套路由”,常见场景比如:有个用户中心页面(/user
),点进去后还有「个人资料」(/user/profile
)和「设置」(/user/settings
)两个子页面,这时候得用嵌套路由 + 多个router-view配合。
步骤分两块:
① 配置路由的children
属性
在router/index.js
里给父路由加children
数组:
const routes = [ { path: '/user', component: User, // 父组件 children: [ { path: 'profile', // 子路径,完整路径是/user/profile component: UserProfile }, { path: 'settings', component: UserSettings } ] } ]
② 在父组件里放router-view
父组件(比如User.vue)负责布局(比如侧边栏),子组件的内容通过router-view渲染:
<template> <div class="user-page"> <aside>用户中心侧边栏</aside> <main> <!-- 子路由组件渲染到这 --> <router-view></router-view> </main> </div> </template>
这样访问/user/profile
时,User组件先渲染,里面的router-view再渲染UserProfile组件;访问/user/settings
同理,嵌套路由的关键是「父路由组件里必须有router-view,用来承载子路由组件」。
router-view和router-link有啥区别?
好多刚学的同学会把这俩搞混,其实它们分工很明确:
- router-link:负责「导航」,相当于带路由功能的
<a>
标签,点击它会触发路由跳转,改变URL,但不会整页刷新,比如<router-link to="/about">lt;/router-link>
,点击后URL变成/about
,同时触发路由匹配。 - router-view:负责「渲染」,相当于“内容容器”,路由匹配到哪个组件,它就把那个组件显示在自己的位置上。
类比一下:router-link像网站的导航栏按钮,router-view像导航栏下面的“内容展示区”——点不同按钮,展示区换不同内容。
咋给router-view渲染的组件传参?
路由传参是高频需求(比如详情页要根据ID显示不同内容),常用的有3种方式,各自场景不同:
方式1:动态路由参数(path里带:id
)
适合「路径里必须体现参数」的场景(比如/article/123
,123是文章ID)。
配置路由时,给path加动态参数:
const routes = [ { path: '/article/:id', // :id是动态参数 component: ArticleDetail } ]
组件里用this.$route.params.id
(Vue2)或useRoute().params.id
(Vue3)拿参数,比如ArticleDetail.vue里:
<script> export default { mounted() { console.log(this.$route.params.id) // 拿到动态参数 } } </script>
方式2:查询参数(?id=123
)
适合「参数可选,或多个参数」的场景(比如列表页筛选?keyword=Vue&page=2
)。
跳转时用<router-link to="/list?keyword=Vue">
,或编程式导航:
this.$router.push({ path: '/list', query: { keyword: 'Vue' } })
组件里用this.$route.query.keyword
(Vue2)或useRoute().query.keyword
(Vue3)获取,好处是参数在URL里可见,刷新页面参数还在;缺点是路径变长。
方式3:props传参(路由配置里开props
)
适合「组件想通过props接收参数,解耦$route依赖」的场景。
路由配置里加props: true
:
const routes = [ { path: '/article/:id', component: ArticleDetail, props: true // 开启后,$route.params.id会自动传给组件的props } ]
然后组件里定义props:
<script> export default { props: ['id'], // 接收id参数 mounted() { console.log(this.id) // 直接用props,不用$route了 } } </script>
这种方式让组件更“纯”,不直接依赖路由实例,后期维护或复用更方便。
想缓存router-view渲染的组件状态,咋做?
默认情况下,切换路由时,router-view渲染的组件会被销毁(比如从列表页到详情页,再回来,列表页会重新加载),如果想保留组件状态(比如表单填了一半,切回来不想重新填),得用<keep-alive>
包裹router-view。
用法很简单,在App.vue里把router-view包起来:
<template> <div id="app"> <router-link to="/">首页</router-link> <router-link to="/form">表单页</router-link> <!-- 用keep-alive缓存 --> <keep-alive> <router-view></router-view> </keep-alive> </div> </template>
这样组件切换时,会被缓存而不是销毁,再次进入时会触发activated
钩子(而不是created/mounted
)。
如果想精细控制哪些组件缓存、哪些不缓存,还能加include/exclude
属性:
<keep-alive include="FormComponent,ListComponent"> <router-view></router-view> </keep-alive>
include
里写组件的name
(要和组件定义的name
一致),只有这些组件会被缓存;exclude
则是排除某些组件。
给router-view加过渡动画,咋实现?
Vue本身支持过渡动画,给router-view加动画,核心是用<transition>
或<transition-group>
包裹它,配合CSS定义进入、离开的动画。
举个「渐变切换」的例子:
① 用<transition>
包裹router-view,给个name
在App.vue里:
<template> <div id="app"> <router-link to="/">首页</router-link> <router-link to="/about">lt;/router-link> <transition name="fade"> <router-view></router-view> </transition> </div> </template>
② 写CSS动画
.fade-enter-active, .fade-leave-active { transition: opacity 0.5s; } .fade-enter-from, .fade-leave-to { opacity: 0; }
这样切换路由时,组件会有淡入淡出效果,如果想要滑动、缩放等更复杂的动画,原理一样:给transition
加name
,然后在CSS里定义enter/leave
的起始、结束状态和过渡时间。
要是多个路由切换需要不同动画,还能结合路由元信息(meta),动态给transition
加name
,实现更灵活的效果。
页面有多个区域要渲染不同路由组件,咋用router-view?
有时候页面布局复杂,比如顶部导航、左侧菜单、右侧内容、底部版权,每个区域都要根据路由渲染不同组件,这时候得用「命名视图」。
步骤:
① 路由配置里用components
(复数),给每个组件配name
const routes = [ { path: '/dashboard', components: { header: DashboardHeader, // name是header sidebar: DashboardSidebar, // name是sidebar main: DashboardMain // name是main } } ]
② 页面里用带name
的router-view
<template> <div class="dashboard"> <router-view name="header"></router-view> <div class="content"> <router-view name="sidebar"></router-view> <router-view name="main"></router-view> </div> <router-view name="footer"></router-view> </div> </template>
这样访问/dashboard
时,name
为header
的router-view渲染DashboardHeader,name
为sidebar
的渲染DashboardSidebar,以此类推,命名视图让一个路由能同时渲染多个组件到页面不同位置,特别适合复杂布局的场景。
router-view是Vue Router里承上启下的关键组件:从基础的单页面切换,到嵌套路由、传参、缓存、动画、多区域渲染,所有和“路由组件显示”有关的需求,都得靠它来实现,把上面这些场景吃透,不管是做后台管理系统的复杂嵌套,还是移动端App的页面切换,路由这块都能玩得转~要是你还有其他关于router-view的疑问,评论区随时聊~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。