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原型上的属性、方法。