返回

看 VueRouter 源码如何实现 router-view

前端

前言

VueRouter 源码学习 系列文章中,我们已经介绍了 VueRouter 的整体架构、实现原理以及一些核心组件的实现,比如 createMatchercreateRouterhistorylocationRouteRecord 等。本篇我们将继续学习 VueRouter 源码,重点关注 router-view 组件的实现。

函数式组件

在介绍 router-view 组件之前,我们先简单了解一下函数式组件。函数式组件是 Vue 2.0 中引入的一种新的组件类型,它是一个简单的 JavaScript 函数,接收 props 参数并返回一个虚拟 DOM (VNode) 对象。函数式组件通常用于创建一些简单的组件,比如列表项、按钮等。

函数式组件具有以下特点:

  • 它是纯函数,即给定相同的 props,它总是返回相同的 VNode 对象。
  • 它没有实例,所以没有生命周期钩子函数。
  • 它不能使用 this

函数式组件的优点是:

  • 它们更简单、更易于理解和维护。
  • 它们性能更好,因为它们不需要创建组件实例。

函数式组件的缺点是:

  • 它们不能使用生命周期钩子函数,所以无法在组件创建、更新和销毁时执行一些操作。
  • 它们不能使用 this 关键字,所以无法访问组件实例的属性和方法。

router-view 组件的实现

router-view 组件是 VueRouter 中的一个核心组件,它负责渲染当前激活的路由组件。router-view 组件是一个函数式组件,它接收 routeparent 两个 props 参数。

  • route 参数是当前激活的路由记录。
  • parent 参数是当前 router-view 组件的父组件。

router-view 组件的实现主要分为以下几个步骤:

  1. 获取渲染记录。
  2. 标记 router-view 层级深度。
  3. router-view 渲染。

获取渲染记录

router-view 组件首先需要获取渲染记录。渲染记录是一个数组,其中包含了当前激活的路由记录的所有子路由记录。渲染记录是通过调用 getMatchedComponents 方法获得的。

const matched = getMatchedComponents(route)

标记 router-view 层级深度

接下来,router-view 组件需要标记 router-view 层级深度。router-view 层级深度是指当前 router-view 组件在整个路由视图中的层级深度。router-view 层级深度是通过调用 getDepth 方法获得的。

const depth = getDepth(parent)

router-view 渲染

最后,router-view 组件需要渲染当前激活的路由组件。router-view 组件的渲染过程如下:

  1. 首先,它会创建当前激活的路由组件的 VNode 对象。
  2. 然后,它会将 VNode 对象传递给父组件,让父组件进行渲染。

router-view 组件的实现代码如下:

export default {
  functional: true,

  props: {
    route: {
      type: Object,
      required: true
    },
    parent: {
      type: Object,
      required: false
    }
  },

  render (h, { props, data }) {
    const route = props.route
    const matched = getMatchedComponents(route)
    const depth = getDepth(props.parent)
    const record = matched[depth]

    if (!record) {
      return h()
    }

    const component = record.component

    return h(component, {
      key: record.path,
      props,
      parent: props.parent,
      data
    })
  }
}

总结

本篇我们介绍了 VueRouter 源码中 router-view 组件的实现,主要涉及函数式组件的介绍、router-view 组件的实现、获取渲染记录、标记 router-view 层级深度以及 router-view 渲染等内容。通过对 router-view 组件的实现的学习,我们可以更深入地理解 VueRouter 的工作原理。