11. 组件的虚拟节点

组件的虚拟节点

分全局组件 和 局部组件

全局组件

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方法, 生成虚拟节点, 然后生成真实节点, 插入到父元素中

posted @ 2022-06-28 03:04  littlelittleship  阅读(46)  评论(0编辑  收藏  举报