「这是我参与2022首次更文挑战的第25天,活动详情查看:2022首次更文挑战」
Vue.js源码分析 - 组件化
接下来我们要进行回顾Vue
的组件化,组件化是Vue
中的一个很重要的概念,Vue
的核心组成就是数据绑定和组件化
组件化回顾
- 一个 Vue 组件就是一个拥有预定义选项的一个 Vue 实例
- 一个组件可以组成可以组成页面上一个功能完毕的区域,组件可以包含
- 脚本
- 样式
- 模板
就和下图一样,我们可以把页面分割成很多的模块,到时候我们可以按需拼接在一起,就和积木块一样,每一个组件中可能有嵌套了其他颗粒度更小的组件,让我们可以更方便的可以进行复用
这就引发了一个问题:
- 组件的颗粒度是越小越好吗?
欢迎评论讨论!
组件注册
我们先来回顾下 组件的注册方式
- 全局注册:在页面中任意的范围都可以进行使用
- 局部注册:仅仅在当前注册范围中可以使用
接下来我们通过一段代码来回忆一下组件的注册方式
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
}
复制代码