文章目录
- VueComponent构造函数
- 内置关系
VueComponent构造函数
我们已经知道了如何去创建一个组件,例如以下代码:
<body>
<div id="root">
<school></school>
</div>
</body>
<script>//创建school组件
const school = Vue.extend({
name:'NEFU',
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{schoolAddress}}</h2>
<hr>
</div>
`,
data(){
return {
schoolName:'NEFU',
schoolAddress:'哈尔滨',
}
},
})
new Vue({
el:'#root',
//注册组件
components:{
school
},
})</script>
但是我们不知道这个const后面的school到底是什么?或者说它是什么类型的数据?我们可以把它打印出来看看:
由此我们可知组件的本质是一个函数,而且还是一个构造函数(因为函数名的每个单词开头是大写的)!它不是由程序员定义的,是Vue.extend生成的
既然是构造函数,不应该使用new去使用它吗?
事实上,我们只需要写<school/>或<school></school>这样的组件标签,Vue解析时会帮我们创建school组件的实例对象,即Vue帮我们执行的:new VueComponent(options)。
现在我们继续添加一个组件hello:
<body>
<div id="root">
<school></school>
<hello></hello>
</div>
</body>
<script>//创建school组件
const school = Vue.extend({
name:'NEFU',
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{schoolAddress}}</h2>
<hr>
</div>
`,
data(){
return {
schoolName:'NEFU',
schoolAddress:'哈尔滨',
}
},
})
const hello = Vue.extend({
template:`
<h2>{{msg}}</h2>
`,
data(){
return {
msg:'你好啊,CSDN'
}
}
})
new Vue({
el:'#root',
//注册组件
components:{
school,
hello
},
})
console.log(school);</script>
要注意如果你在控制台输出school、hello,会发现是两个一模一样的构造函数:
但是事实上的每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!
我们可以试验一下,我在school的身上添加一个属性a
并令其值为99:
school.a = 99
console.dir(school);
console.dir(hello);
结果:
如此可以证明两个构造函数是完全不同的。
接下来我们继续讨论一个问题:this指向
(1).组件配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【VueComponent实例对象】。
(2).new Vue(options)配置中:
data函数、methods中的函数、watch中的函数、computed中的函数 它们的this均是【Vue实例对象】。
我们可以验证:
首先在school组件里添加一个按钮,绑定一个点击事件,然后控制台输出this即可:
//创建school组件
const school = Vue.extend({
name:'NEFU',
template:`
<div>
<h2>学校名称:{{schoolName}}</h2>
<h2>学校地址:{{schoolAddress}}</h2>
<button @click="haha">点我查看this</button>
<hr>
</div>
`,
data(){
return {
schoolName:'NEFU',
schoolAddress:'哈尔滨',
}
},
methods: {
haha(){
console.log(this)
}
},
})
结果:
如何证明vm管理着几个组件:
点开我们可以直接看到刚才的组件实例对象VueComponent(简称vc)
vc和vm并不是相同的:
他们之间有一个例外
el
内置关系
这里我们有一个重要的内置关系:
VueComponent.prototype.__proto__ === Vue.prototype
我们可以来分析一波:
①实例对象上只会出现隐式原型对象(_proto_)。构造函数上才会出现显式原型对象(prototype)
②不管是显示原型对象还是隐式原型对象最终指向的都是原型对象
显然Vue的原型对象它也是对象,既然是对象那么就有隐式原型对象,因为它是通过new Object出来的,所以它的隐式原型对象就是Object的原型对象,所以:
然后我们把组件给加入进来:
按理说下一步,VueComponent的原型对象的隐式原型对象应该指向Object的原型对象:
但是并不是这样,事实上VueComponent的原型对象的隐式原型对象指向了Vue的原型对象:
我们可以来验证一下:
我们在Vue的原型对象上放一个属性a,并令它为99,然后通过VueComponent去拿到他:
这样做的目的我们可以这样理解:Vue想让Vue的原型对象作为一个最终保险人,如果Vue的原型对象都没有办法,再交给Object的原型对象。
再来更具体的理解:
让组件实例对象(vc)可以访问到 Vue原型上的属性、方法。
验证:
<body>
<!-- 准备好一个容器-->
<div id="root">
<school></school>
</div>
</body>
<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。
Vue.prototype.x = 99
//定义school组件
const school = Vue.extend({
name:'school',
template:`
<div>
<h2>学校名称:{{name}}</h2>
<h2>学校地址:{{address}}</h2>
<button @click="showX">点我输出x</button>
</div>
点击按钮结果是: