vue2.x之深入理解组件实例VueComponent

我们在使用vue组件的时候,可能搭个脚手架就开始创建.vue文件了,然后在需要使用的页面或组件中再引入组件开始使用,很少去关注组件内部的东西,其实VueComponent,也叫组件实例在vue组件中是个很重要的概念,能够帮助我们更深入理解组件,以及后面看vue源码也会更加容易。

组件到底是什么

从代码层面来看,组件的本质就是一个名叫VueComponent的构造函数。 这里以非单文件组件来看:

<body>
    <!-- 准备一个容器 -->
    <div id="root">
        <test></test>
    </div>
    <!-- 准备一个Vue实例 -->
    <script>
        Vue.config.productionTip = false;
        //定义一个组件实例
        const test = Vue.extend({
            name: 'test',
            template: '<p>{{firstName}} - {{lastName}}</p>',
            data(){
                return {
                    firstName: 'Walter',
                    lastName: 'White',
                }
            }
        });
        
        //创建一个根组件实例
        const vm = new Vue({
            el: '#root', //可以是一个CSS选择器也可以是一个HTMLElement实例,一般选用CSS选择器中的id来标识
            components: { test }, //注册test组件
            data() {
                return {

                }
            },
        })
        console.log(test);
    </script>
</body>

效果如下:

❓那为什么会是一个VueComponent的构造函数,是因为我们在创建vue组件的时候,调用了 Vue.extend,这个方法底层会帮我们创建VueComponent的构造函数。具体如下:

Vue.extend = function(extendOptions: Object): Function {
    // 此处省略。。。
    
    // 创建Sub构造函数
    const Sub = function VueComponent(options) {
      this._init(options)
    }
    // 此处省略。。。
    
    return Sub
}

我们只需要写或<test/>,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的: new VueComponent(options).

❗️每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!也就是说我们每次在页面中引入同一个组件都是一个全新的VueComponent。

<body>
    <!-- 准备一个容器 -->
    <div id="root">
        <test1></test1>
        <test2></test2>
    </div>
    <!-- 准备一个Vue实例 -->
    <script>
        Vue.config.productionTip = false;
//定义一个组件实例 const test1 = Vue.extend({ name: 'test', template: '<p>{{firstName}} - {{lastName}}</p>', data() { return { firstName: 'Walter', lastName: 'White', } } }); //定义一个组件实例 const test2 = Vue.extend({ name: 'test', template: '<p>{{firstName}} - {{lastName}}</p>', data() { return { firstName: 'Walter', lastName: 'White', } } }); //创建一个根组件实例 const vm = new Vue({ el: '#root', //可以是一个CSS选择器也可以是一个HTMLElement实例,一般选用CSS选择器中的id来标识 components: { test1, test2 }, //注册test组件 data() { return { } }, }) console.log(test1 === test2); </script> </body>

效果如下:

this指向

1.组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是VueComponent实例对象
2.new Vue(options)能置中:data阴数、methods中的函数、watch中的两数、computed中的函数 它们的this均是Vue实例对象

<body>
    <!-- 准备一个容器 -->
    <div id="root">
        <test></test>
    </div>
    <!-- 准备一个Vue实例 -->
    <script>
        Vue.config.productionTip = false;
        //定义一个组件实例
        const test = Vue.extend({
            name: 'test',
            template: '<p>{{firstName}} - {{lastName}}</p>',
            data() {
                return {
                    firstName: 'Walter',
                    lastName: 'White',
                }
            },
            created() {
                console.log('组件this', this);
            },
        });

        //创建一个Vue实例
        const vm = new Vue({
            el: '#root', //可以是一个CSS选择器也可以是一个HTMLElement实例,一般选用CSS选择器中的id来标识
            components: { test }, //注册test组件
            created() {
                console.log('vue的this', this);
            },
        })
        console.log(test);
    </script>
</body>

效果如下:

  • vue的this

  • 组件的this

vue实例和组件实例的关系

从上面vue实例和组件实例的打印关系我们可以看出,vue实例内部属性和组件实例的内部属性非常相似,那么它们之间有什么关系呢?

从这个图我们可以看出一个重要的内置关系:VueComponent.prototype.__proto=== Vue.prototype。 之所以有这个关系主要就是让组件实例对象可以访问到 Vue原型上的属性、方法。

posted on 2024-07-10 13:27  梁飞宇  阅读(60)  评论(0)    收藏  举报