组件的虚拟节点
分全局组件 和 局部组件
全局组件
Vue.component('my-button', {
template: '<button>点击</button>'
})
局部组件
const vm = new Vue({
el: '#app',
data() {
return {name: '123'}
},
components: {
'my-button': {
template: '<button>inner 点击</button>'
}
}
})
同时出现上面两个组件时, 优先自己的组件, 类似js中的原型链, 内部可能时一个继承的模型
里面有个api, Vue.extend
上面的直接写一个对象其实是简写
Vue.component('my-button', Vue.extend({
template: '<button>点击</button>'
})
...
const vm = new Vue({
el: '#app',
data() {
return {name: '123'}
},
components: {
'my-button':Vue.extend({
template: '<button>inner 点击</button>'
})
}
})
Vue.extend 使用基础构造器, 创造一个子类
组件的创建很复杂, 在组件中定义component不是像initData, initComputed一样
先熟悉两个全局的api
Vue.extend: 返回一个子类Sub, 该子类的原型指向Vue的原型, 并且通过静态属性保存用户选项
Vue.extend = function(options) {
// 根据用户的参数, 返回一个构造函数
function Sub(options = {}) { // 最终使用一个组件, 就是new 一个实例
this._init(options)
}
// 复用Vue原型, Sub.prototype.__proto__ === Vue.prototype, 让Sub的原型能找到Vue原型上
Sub.prototype = Object.create(Vue.prototype)
Sub.prototype.constructor = Sub // 配套使用
// 保存用户的选项
Sub.options = options
return Sub
}
Vue.component: 保存全局组件, 并调用Vue.extend()方法
Vue.options.components = {} // 全局组件
Vue.component = function(id, definition) {
// definition可能是对象, 就要 Vue.etend(),
definition = typeof definition === 'function' ? definition : Vue.extend(definition)
Vue.options.components[id] = definition
}
创建子组件的过程:
当执行vm._render方法生成虚拟节点的时候, 通过标签判断这个tag是不是组件, 如果是, 就会在$options的组件中, 找到这个组件的定义, 并执行Vue.extend(definition)放回一个Sub类, 然会new Sub(), 会执行this._init()方法, 就是Vue构造函数里面的方法,过程中有一步是mergeOptions, 合并全局的组件, 然后也会执行$mount方法, 生成虚拟节点, 然后生成真实节点, 插入到父元素中
原创文章,作者:jamestackk,如若转载,请注明出处:https://blog.ytso.com/270580.html