或者Vue3项目用,npm install vue-router@4
刚学Vue路由的小伙伴,十有八九会纠结:
Vue Router View 是做什么的?
你可以把<router-view>
理解成的容器”,Vue单页应用(SPA)里,页面切换不需要整页刷新,而是靠路由规则匹配对应的组件,再把这个组件“塞”到<router-view>
里渲染。
举个生活例子:你家楼下的快递柜,每个格子对应一个“路由规则”(比如取件码是路径),<router-view>
就是整个快递柜——当你输入取件码(访问对应路径),对应的快递(组件)就会出现在柜子里(被<router-view>
渲染出来)。
从技术角度说,Vue Router 是管理路由的插件,<router-view>
是它提供的内置组件,只要在模板里写了<router-view>
,Vue Router 就会自动把当前匹配到的路由组件,替换到这个位置,比如做一个多页面感的SPA,首页、关于页、商品详情页这些不同页面,全靠<router-view>
来“动态换内容”。
怎么在项目里引入并使用 Router View?
想用<router-view>
,得先把Vue Router 整套流程跑通,分4步走:
安装Vue Router(先把工具备好)
如果是Vue2项目,用npm/yarn安装:
npm install vue-router@3 # Vue2对应router3.x版本``` #### 2. 配置路由规则(告诉路由“哪个路径对应哪个组件”) 新建`router.js`(或`router/index.js`),写路由规则: ```js import Vue from 'vue' import VueRouter from 'vue-router' // 引入要渲染的组件 import Home from './views/Home.vue' import About from './views/About.vue' Vue.use(VueRouter) // 全局注册VueRouter插件 // 定义路由规则:path是路径,component是对应组件 const routes = [ { path: '/', // 根路径 component: Home // 访问/时,渲染Home组件 }, { path: '/about', // 路径/about component: About // 渲染About组件 } ] // 创建路由实例 const router = new VueRouter({ routes // 把规则传进去 }) export default router // 导出,给main.js用
把路由注入Vue根实例(让整个项目能用上路由)
打开main.js
,把路由实例挂到Vue上:
import Vue from 'vue' import App from './App.vue' import router from './router' // 引入刚才写的路由配置 new Vue({ router, // 注入路由,整个项目就能用this.$router和this.$route了 render: h => h(App) }).$mount('#app')
在模板里用<router-view>
(指定“动态内容该显示在哪”)
比如在App.vue
(项目的根组件)里,写导航和<router-view>
:
<template> <div id="app"> <!-- 导航链接:点击切换路径 --> <router-link to="/">首页</router-link> <router-link to="/about">lt;/router-link> <!-- 关键:路由匹配到的组件,会渲染到这里 --> <router-view></router-view> </div> </template>
到这一步,启动项目后,点击<router-link>
,<router-view>
就会自动切换成Home或About组件——基础用法就跑通了~
Router View 怎么实现路由嵌套?(比如后台管理系统的布局)
很多项目有“嵌套结构”:比如后台管理页面,顶部有导航栏、左侧有侧边栏,区要根据子路由切换(点侧边栏“订单管理”,内容区变订单列表;点“用户管理”,内容区变用户列表),这时候就得用嵌套路由,而<router-view>
要在“父组件”里再放一次。
实操步骤:
以“仪表盘(Dashboard)”为例,父路由是/dashboard
,子路由是/dashboard/analysis
(数据分析)、/dashboard/statistics
(数据统计)。
-
写父组件(DashboardLayout):负责渲染侧边栏、顶栏,中间留
<router-view>
给子组件。<template> <div class="dashboard-layout"> <!-- 侧边栏 --> <aside> <router-link to="/dashboard/analysis">数据分析</router-link> <router-link to="/dashboard/statistics">数据统计</router-link> </aside> <!-- 顶栏 --> <header>仪表盘</header> <!-- 子路由的内容,要渲染到这里! --> <router-view></router-view> </div> </template>
-
配置嵌套路由规则:在
router.js
里,给父路由加children
数组:const routes = [ // 其他路由... { path: '/dashboard', component: DashboardLayout, // 父组件 children: [ // 子路由规则 { path: 'analysis', // 注意:路径不用写全,父路径是/dashboard,所以这里是analysis → 完整路径/dashboard/analysis component: Analysis // 子组件:数据分析页面 }, { path: 'statistics', component: Statistics // 子组件:数据统计页面 } ] } ]
-
访问测试:当你访问
/dashboard/analysis
时,Vue Router 会先匹配父路由/dashboard
,渲染DashboardLayout
组件,然后DashboardLayout
里的<router-view>
会渲染子路由analysis
对应的Analysis
组件——嵌套效果就实现了!
Router View 传参有哪些方式?(让组件知道“我该显示谁的数据”)
路由传参是为了让组件拿到“动态信息”,比如用户ID、商品ID、筛选条件等,常见有3种方式,适用场景不同:
动态路由传参(路径里带参数,比如/user/123
)
用法:在路由规则的path
里用:参数名
,
{ path: '/user/:id', // :id是动态参数 component: UserDetail }
取值:在UserDetail
组件里,通过this.$route.params.id
拿到参数(比如123)。
场景:适合“一对一”的详情页,比如用户详情、商品详情——路径直观,SEO友好(搜索引擎能抓到具体路径)。
查询参数传参(路径后带?xxx=yyy
,比如/user?name=张三
)
用法:不需要改路由规则的path
,直接在<router-link>
或this.$router.push
里传query
对象:
<!-- 用router-link传参 --> <router-link :to="{ path: '/user', query: { name: '张三', age: 18 }}"> 跳转到用户页 </router-link> <!-- 用js编程式导航传参 --> this.$router.push({ path: '/user', query: { name: '张三', age: 18 } })
取值:在组件里用this.$route.query.name
、this.$route.query.age
拿参数。
场景:适合“筛选、搜索”类需求,比如列表页的筛选条件(页码、关键词)——参数可多可少,且刷新页面参数不会丢(因为在URL里)。
路由元信息(meta
字段,藏在路由规则里)
用法:在路由规则里加meta
对象,存自定义信息:
{ path: '/', component: Home, meta: { '首页', // 页面标题 requiresAuth: true // 是否需要登录(权限控制用) } }
取值:在组件里用this.$route.meta.title
、this.$route.meta.requiresAuth
拿信息。
场景:适合全局控制的逻辑,比如页面标题(路由守卫里改文档标题)、权限判断(进入页面前检查是否登录)、缓存标记(配合<keep-alive>
用)等。
怎么给 Router View 加页面缓存?(返回页面时,数据和状态不丢失)
比如用户从“商品列表页”点进“商品详情页”,返回列表页时,希望列表的滚动位置、已加载的数据还在——这就得用<keep-alive>
缓存<router-view>
。
基础用法:直接包裹<router-view>
在模板里,用<keep-alive>
把<router-view>
包起来:
<template> <div> <!-- keep-alive会缓存路由组件,切换时不销毁 --> <keep-alive> <router-view></router-view> </keep-alive> </div> </template>
这样,被缓存的组件不会触发created
/mounted
等生命周期(因为没被销毁),而是触发activated
和deactivated
钩子,比如列表页要在activated
里刷新数据(如果需要):
export default { activated() { // 组件被激活时(从缓存里拿出来用),执行刷新逻辑 this.fetchData() }, deactivated() { // 组件被缓存时,执行暂停逻辑(比如停止定时器) } }
进阶:控制“哪些组件要缓存”
如果有的页面不需要缓存(比如登录页),可以结合路由元信息+<keep-alive>
的include
属性:
-
给路由规则加
meta.keepAlive
标记:{ path: '/product/list', component: ProductList, meta: { keepAlive: true } // 需要缓存 }, { path: '/login', component: Login, meta: { keepAlive: false } // 不需要缓存 }
-
在模板里,让
<keep-alive>
的include
只包含需要缓存的组件名:<template> <div> <keep-alive :include="cachedComponents"> <router-view></router-view> </keep-alive> </div> </template>
这样只有ProductList
这类标记了keepAlive: true
的组件会被缓存,登录页切换时就会销毁重建~
Router View 结合过渡动画怎么玩?(让页面切换更丝滑)
Vue的<transition>
组件能给元素加“进入/离开”动画,和<router-view>
结合,就能实现页面切换的渐变、滑动等效果。
基础玩法:全局渐变动画
给<router-view>
包一层<transition>
,并定义CSS过渡:
-
模板里加
<transition>
:<template> <div> <transition name="fade"> <router-view></router-view> </transition> </div> </template>
-
写CSS样式(
fade
是<transition>
的name
,对应类名):/* 进入和离开时的过渡时间、动画曲线 */ .fade-enter-active, .fade-leave-active { transition: opacity 0.5s ease; } /* 进入前的状态、离开后的状态 */ .fade-enter-from, .fade-leave-to { opacity: 0; }
这样切换路由时,页面会有0.5秒的淡入淡出效果~
进阶玩法:不同页面不同动画
首页→关于页”是滑动动画,“列表页→详情页”是缩放动画,这需要动态控制<transition>
的name
,配合路由元信息:
-
给路由规则加
meta.transitionName
:{ path: '/', component: Home, meta: { transitionName: 'slide-left' } }, { path: '/about', component: About, meta: { transitionName: 'slide-right' } }
-
模板里让
<transition>
的name
动态绑定:<template> <div> <transition :name="$route.meta.transitionName"> <router-view></router-view> </transition> </div> </template>
-
写对应的CSS(以滑动为例):
.slide-left-enter-active, .slide-left-leave-active, .slide-right-enter-active, .slide-right-leave-active { position: absolute; /* 让页面切换时不挤在一起 */ width: 100%; transition: all 0.3s ease; }
/ 从左边进入(首页→关于页) / .slide-left-enter-from { transform: translateX(-100%); } .slide-left-leave-to { transform: translateX(100%); }
/ 从右边进入(关于页→首页) / .slide-right-enter-from { transform: translateX(100%); } .slide-right-leave-to { transform: translateX(-100%); }
这样不同页面切换时,动画就不一样啦~
### Router View 遇到404页面怎么处理?(用户访问了不存在的路径)
项目里总得有个“兜底”页面:当用户输入的路径没匹配到任何路由规则时,跳转到404页面。
#### 实操步骤:
1. 写404组件(NotFound.vue):
```vue
<template>
<div>
<h1>404 - 页面走丢啦!</h1>
<router-link to="/">返回首页</router-link>
</div>
</template>
- 在路由规则里加“通配符路由”(放在最后!因为路由匹配是从上到下的):
const routes = [ // 其他路由规则... { // path里的/:pathMatch(.*)* 是Vue Router的通配符,匹配所有未匹配的路径 path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound } ]
这样,当用户访问/abc
、/xxx/yyy
等不存在的路径时,<router-view>
就会渲染NotFound组件,引导用户返回~
Router View 性能优化要注意啥?
虽然<router-view>
本身性能不错,但项目大了也得注意这些点:
路由懒加载(减少首屏加载体积)
如果所有组件都在首屏加载,会导致打包后的JS文件很大,首屏变慢,用动态导入(import()
)实现懒加载:
{ path: '/about', // 把component改成函数,按需加载 component: () => import('./views/About.vue') }
这样About组件会在用户访问/about
时才加载,首屏只加载必要组件~
合理用<keep-alive>
缓存(避免重复渲染)
如果页面切换时,组件里的请求、计算逻辑很耗时,可以用<keep-alive>
缓存,但要注意:不需要缓存的页面别硬塞(比如登录页、404页),否则会占用内存,结合前面讲的“路由元信息+include
”精准控制缓存。
拆分大组件(让缓存更高效)
如果一个路由组件特别大(比如几百个组件嵌套),可以拆成更小的子组件,配合<keep-alive>
缓存关键部分,比如把“订单列表+筛选栏+分页”拆成三个子组件,只缓存列表,筛选和分页按需渲染。
路由守卫里少做复杂逻辑
全局路由守卫(如router.beforeEach
)里如果写了大量循环、请求,会拖慢路由切换速度,尽量把复杂逻辑放到组件内的beforeRouteEnter
等钩子,或用Vuex管理异步逻辑。
看完这些问题,是不是觉得
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。