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



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