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




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