开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第18天,点击查看活动详情
我们在使用vue组件的时候,可能搭个脚手架就开始创建.vue文件了,然后在需要使用的页面或组件中再引入组件开始使用,很少去关注组件内部的东西,其实VueComponent,也叫组件实例在vue组件中是个很重要的概念,能够帮助我们更深入理解组件,以及后面看vue源码也会更加容易。
组件到底是什么
从代码层面来看,组件的本质就是一个名叫VueComponent的构造函数。 这里以非单文件组件来看:
<div id="root">
<test></test>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>
<script>
const test = Vue.extend({
name: 'test',
template: '<p>{{firstName}} {{lastName}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
}
}
});
const vm = new Vue({
el: '#root',
components: {test}
});
console.log(test);
</script>
效果如下:
那为什么会是一个VueComponent的构造函数,是因为我们在创建vue组件的时候,调用了 Vue.extend,这个方法底层会帮我们创建VueComponent的构造函数。具体如下:
Vue.extend = function(extendOptions: Object): Function {
// 此处省略。。。
// 创建Sub构造函数
const Sub = function VueComponent(options) {
this._init(options)
}
// 此处省略。。。
return Sub
}
我们只需要写或<testx,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的: new VueComponent(options).
每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!也就是说我们每次在页面中引入同一个组件都是一个全新的VueComponent。
<script>
const test1 = Vue.extend({
name: 'test1',
template: '<p>{{firstName}} {{lastName}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
}
}
});
const test2 = Vue.extend({
name: 'test2',
template: '<p>{{firstName}} {{lastName}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
}
}
});
const vm = new Vue({
el: '#root',
components: {test1, test2}
});
console.log(test1 === test2);
</script>
效果如下:
this指向
- .组件配置中:data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是VueComponent实例对象
- new Vue(options)能置中:data阴数、methods中的函数、watch中的两数、computed中的函数 它们的this均是Vue实例对象
<script>
const test = Vue.extend({
name: 'test2',
template: '<p>{{firstName}} {{lastName}}</p>',
data: function () {
return {
firstName: 'Walter',
lastName: 'White',
}
},
created(){
console.log('组件this', this);
}
});
const vm = new Vue({
el: '#root',
components: {test},
created(){
console.log('vue的this', this);
}
});
</script>
效果如下:
vue实例和组件实例的关系
从上面vue实例和组件实例的打印关系我们可以看出,vue实例内部属性和组件实例的内部属性非常相似,那么它们之间有什么关系呢?
从这个图我们可以看出一个重要的内置关系:VueComponent.prototype.__proto=== Vue.prototype。 之所以有这个关系主要就是让组件实例对象可以访问到 Vue原型上的属性、方法。