Code前端首页关于Code前端联系我们

Vue.js里的router-view到底怎么用?常见问题一次讲清

terry 6小时前 阅读数 8 #Vue
文章标签 js;routerview

做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;
}

这样切换路由时,组件会有淡入淡出效果,如果想要滑动、缩放等更复杂的动画,原理一样:给transitionname,然后在CSS里定义enter/leave的起始、结束状态和过渡时间。

要是多个路由切换需要不同动画,还能结合路由元信息(meta),动态给transitionname,实现更灵活的效果。

页面有多个区域要渲染不同路由组件,咋用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时,nameheader的router-view渲染DashboardHeader,namesidebar的渲染DashboardSidebar,以此类推,命名视图让一个路由能同时渲染多个组件到页面不同位置,特别适合复杂布局的场景。

router-view是Vue Router里承上启下的关键组件:从基础的单页面切换,到嵌套路由、传参、缓存、动画、多区域渲染,所有和“路由组件显示”有关的需求,都得靠它来实现,把上面这些场景吃透,不管是做后台管理系统的复杂嵌套,还是移动端App的页面切换,路由这块都能玩得转~要是你还有其他关于router-view的疑问,评论区随时聊~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门