0
点赞
收藏
分享

微信扫一扫

Vue组件化编程③


文章目录

  • ​​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组件化编程③_原型对象


由此我们可知组件的本质是一个函数,而且还是一个构造函数(因为函数名的每个单词开头是大写的)!它不是由程序员定义的,是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组件化编程③_javascript_02


但是事实上的每次调用Vue.extend,返回的都是一个全新的VueComponent!!!!

我们可以试验一下,我在school的身上添加一个属性​​a​​并令其值为99:

school.a = 99
console.dir(school);
console.dir(hello);

结果:

Vue组件化编程③_vue.js_03


如此可以证明两个构造函数是完全不同的。

接下来我们继续讨论一个问题: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)
}
},
})

结果:

Vue组件化编程③_javascript_04

如何证明vm管理着几个组件:

Vue组件化编程③_构造函数_05


点开我们可以直接看到刚才的组件实例对象VueComponent(简称vc)


Vue组件化编程③_原型对象_06

vc和vm并不是相同的:

Vue组件化编程③_原型对象_07


他们之间有一个例外​

​el​

内置关系

这里我们有一个重要的内置关系:
​​​VueComponent.prototype.__proto__ === Vue.prototype​

我们可以来分析一波:

Vue组件化编程③_javascript_08

①实例对象上只会出现隐式原型对象(_proto_)。构造函数上才会出现显式原型对象(prototype)
②不管是显示原型对象还是隐式原型对象最终指向的都是原型对象

显然Vue的原型对象它也是对象,既然是对象那么就有隐式原型对象,因为它是通过new Object出来的,所以它的隐式原型对象就是Object的原型对象,所以:

Vue组件化编程③_前端_09


然后我们把组件给加入进来:

Vue组件化编程③_javascript_10


按理说下一步,VueComponent的原型对象的隐式原型对象应该指向Object的原型对象:

Vue组件化编程③_构造函数_11


但是并不是这样,事实上VueComponent的原型对象的隐式原型对象指向了Vue的原型对象:

Vue组件化编程③_构造函数_12


我们可以来验证一下:

我们在Vue的原型对象上放一个属性a,并令它为99,然后通过VueComponent去拿到他:

Vue组件化编程③_前端_13


这样做的目的我们可以这样理解: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>

点击按钮结果是:

Vue组件化编程③_vue.js_14


举报

相关推荐

0 条评论