Vue.js源码分析 - 组件化

「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战

Vue.js源码分析 - 组件化

接下来我们要进行回顾Vue的组件化,组件化是Vue中的一个很重要的概念,Vue的核心组成就是数据绑定组件化 组件化.webp

组件化回顾

  • 一个 Vue 组件就是一个拥有预定义选项的一个 Vue 实例
  • 一个组件可以组成可以组成页面上一个功能完毕的区域,组件可以包含
    • 脚本
    • 样式
    • 模板

就和下图一样,我们可以把页面分割成很多的模块,到时候我们可以按需拼接在一起,就和积木块一样,每一个组件中可能有嵌套了其他颗粒度更小的组件,让我们可以更方便的可以进行复用 image.png

这就引发了一个问题:

  • 组件的颗粒度是越小越好吗?

欢迎评论讨论!

组件注册

我们先来回顾下 组件的注册方式

  • 全局注册:在页面中任意的范围都可以进行使用
  • 局部注册:仅仅在当前注册范围中可以使用

接下来我们通过一段代码来回忆一下组件的注册方式

Vue.component('comp', {
      template: '<h1>hello</h1>'
})
复制代码

下来我们来看一下Vue.component的实现

component

Vue.component是一个静态方法

  • 路径:src\core\global-api\assets.js
  • 创建组件的构造函数,挂载到 Vue 实例的 vm.options.component.componentName = Ctor
// src\core\global-api\index.js
// 注册 Vue.directive()、 Vue.component()、Vue.filter()
initAssetRegisters(Vue)

// src\core\global-api\assets.js
if (type === 'component' && isPlainObject(definition)) {
    definition.name = definition.name || id
    definition = this.options._base.extend(definition)
}

……

// 全局注册,存储资源并赋值
// this.options['components']['comp'] = Ctor
this.options[type + 's'][id] = definition

// src\core\global-api\index.js
// this is used to identify the "base" constructor to extend all plain-object
// components with in Weex's multi-instance scenarios.

Vue.options._base = Vue

// src\core\global-api\extend.js

Vue.extend()
复制代码

extend

Vue.component中,如果第二个参数传入的是一个组件选项对象的话,它内部会调用Vue.extend方法把该组件的选项对象转换成对应的选项子类,也就是对应组件的构造函数,所以我们会说:组件也是一个Vue实例

  • 路径 src\core\global-api\extend.js
const Sub = function VueComponent (options) {
    this._init(options)
}

Sub.prototype = Object.create(Super.prototype)
Sub.prototype.constructor = Sub
Sub.cid = cid++
Sub.options = mergeOptions(
    Super.options,
    extendOptions
)
Sub['super'] = Super

// For props and computed properties, we define the proxy getters on
// the Vue instances at extension time, on the extended prototype. This
// avoids Object.defineProperty calls for each instance created.
if (Sub.options.props) {
    initProps(Sub)
}

if (Sub.options.computed) {
    initComputed(Sub)
}

// allow further extension/mixin/plugin usage
Sub.extend = Super.extend
Sub.mixin = Super.mixin
Sub.use = Super.use

// create asset registers, so extended classes
// can have their private assets too.
ASSET_TYPES.forEach(function (type) {
    Sub[type] = Super[type]
})

// enable recursive self-lookup
if (name) {
    Sub.options.components[name] = Sub
}
复制代码

猜你喜欢

转载自juejin.im/post/7066986004795621389