首先,这个问题比较大,对于这种问题,我们可以从多个方面进行分析概括;
其次,要注意回答思路,可以从以下几个方面进行阐述:
- 组件化的定义;
- 组件化的优点;
- 组件化的使用场景和注意事项等;
- vue中组件化的一些特点;
1. 组件化的定义
组件定义:
源码位置:src\core\global-api\assets.js
组件定义的方式:
// 全局组件定义
Vue.component('comp',{
template:'<div>this is a component</div>'
})
在源码中分析问题:
type 其实就是component,filter,directive这三个方法;
在判断条件中,它会接收到‘component’,并且判断definition到底是不是一个对象,如果是组件配置对象,它就会利用extend()方法将其转化为构造函数;
然后,它会在当前vue的选项(options)中加入‘component’选项,如此,定义的全局组件对象,将会继承在所有的子组件中去;
我们再看一下extend方法:
源码位置:src\core\global-api\extend.js
在这个文件中,存在一个VueComponent类,它还是继承与Vue的,所以,Sub其实就是一个子类,它继承于Vue;
通过“选项合并”,进行全局组件和局部组件的合并,然后就都可以在当前这个vue实例中正常使用;
对于单文件组件来说:
// 单文件组件形式
<template>
<div>
this is a component
</div>
</template>
vue-loader会编译template为render函数,最终导出的依然是组件配置对象;
其实,单文件组件并非真正意义上的组件,它只是一个vue组件配置对象;
.vue文件最后也会被编译为.js文件(或者js对象,它只是一个配置对象);
2. 组件化的优点
源码位置:vue\src\core\instance\lifecycle.js---mountComponent()
组件其实和Watch有一一对应的关系,这个我们可以在源码中看出来:
mountComponent()方法就是组件的实例,在执行$mount时会被调用,执行这个方法时,每一个组件都一个Watch,当组件发生变化时,它只会更新发生变化的组件,其他组件则不会发生更新,不仅节省性能,而且效率更高;
3. 组件化的实现
- 组件的构造函数
- 实例化及挂载
构造函数源码:src\core\global-api\extend.js
实例化及挂载源码:src\core\vdom\patch.js---createElm()
extend.js文件上面我们已经介绍过了,这里就不再说了;
那么,我们来看一下patch.js中的createElm()方法:
这段代码会判断当前创建的到底是不是一个组件,如果不是,则不会执行创建过程(createComponent());
如果是自定义组件,则会执行createComponent(),j进行组件的创建;
实例化及挂载是在create-component.js中完成的:
源码位置:src\core\vdom\create-component.js----componentVNodeHooks()方法
4. 结论
- 组件是独立和可复用的代码组织单元,组件系统是Vue核心特性之一,它使开发者使用小型,独立和通常可复用的组件构建大型应用;
- 组件化开发能大幅度提高应用开发效率,测试性,复用性等;
- 组件使用按分类有:页面组件,业务组件,通用组件;
- vue的组件是基于配置的,我们通常编写的组件是组件配置的而非组件,框架后续会生成其构造函数,他们基于VueComponent,扩展于Vue;
- vue中常见组件化技术:属性prop,自定义事件,插槽等,他们主要用于组件通信,扩展等;
- 合理的划分组件,有助于提升应用性能;
- 组件应该是高内聚,低耦合的;
- 遵循单向数据流的原则;