Vue.extend( )是一个组件构造器
1. 组件(component)
- 组件化思维
组件化针对的是页面中的整个完整的功能模块划分 (项目的分工) - 组件的概念( 一个文件 )
组件是一个html、css、js、image等外链资源,这些部分组成的一个聚合体
优点:代码复用,便于维护
划分组件的原则:复用率高的,独立性强的
-
vue.js文件中暴露出一个Vue的构造器函数, 这个函数的作用,是用来实例化出来一个实例, 那么这个实例也是一个组件, 我们称之为 ‘根实例’
-
我们从vue detools(Vue 的调试工具)中我们发现这个实例的表现形式是一个标签 (指的是)
-
Vue为了扩展功能, 给了一个方法 , 这个方法叫 extend
-
我们对比 Vue vs Vue.extend() 我们发现这两个方法输出结果都是两个构造器函数, 并且很相似 但是不能够 new Vue.extend( )
它不需要实例化, new Vue.extend( ) 会报错,如果可以实例化的化,组件的出现就没有必要了,因为Vue本身new 完之后就可以在其里面写很多东西。它希望的组件表现的形式应该是标签,并且如果要像标签一样使用,那么应该遵守H5的标准,所以说组件必须合法,在这之前要先注册。所以使用之前必须注册。
Vue.extend({
template: 模板,
data(){},
mthods: {},
watch: {},
computed:{}
})
//在new Vue()里面能写的,Vue.extend里面都能写,因为都是Vue.extend()里面继承的。
//对于data比较特殊。除了在new Vue()根实例里面其他的地方都是写成函数的形式。
new Vue({
el: '#app',
})
对于上面的举例是用不了的,因为还没有注册
-
组件的注册
- 全局注册
- 局部注册
- 组件的表现形式是标签
- 组件的命名规范
推荐采用两种命名规范 第一种是 kebab-case(短横线分隔)命名
第二种是 PascalCase (首字母大写)大驼峰命名法
因为这两种命名规范可以更好的和正常的html标签区分开来,告诉别人这个标签不是原生的html标签
问题:Vue.extend从哪来的?
局部注册 //应用在所注册的那个new Vue实例
应用
<body>
<div id="app">
<Hello></Hello> //在页面显示的就是 hellow component
//这一对标签hellow代表的就是template 后面的所有内容
</div>
</body>
var Hello = Vue.extend({
template: '<div> hello component </div>'
})
new Vue({
el: '#app',
components: {
'Hello': Hello //在这里,前面字符串的hellow代表组件名,指的是写在html里的那个标签的名字,后面那个代表配置项,就是指的将配置项赋给那个变量的名字
}
})
全局注册 //应用在所有的new Vue实例中
<body>
<div id="app">
<Hello></Hello>
<Hello/> //无论全局还是局部注册 标签都支持双标签或者单标签
</div>
</body>
var Hello = Vue.extend({
template: '<div> hello component </div>'
})
Vue.component('Hello',Hello)
new Vue({
el: '#app'
})
上面的属于标准写法
随着Vue 2.X版本的到来,组件可以简写
全局简写
Vue.component('Hello',{
template: '<h3> Hello 全局注册</h3>',
mthods: {},
data(){},
watch: {},
computed:{} //同样这些是一样的可以写
})
局部简写
<body>
<div id="app">
<lxl></lxl>
</div>
</body>
new Vue({
el: '#app',
components: {
'lxl': {
template: '<div> hellow</div>'
}
}
})
3. 组件的嵌套
一般人第一感觉以为组件的嵌套是
<body>
<div id="app">
<Father>
<Son></Son>
</Father>
</div>
</body>
注:实际上这样是错误的,Father(组件)的渲染内容是由配置项中的template决定的,所以会把Son(组件)覆盖掉Father里面写任何东西都是一样会被覆盖
根据这个我们得到一个思路,既然Father的渲染内容是由配置项中的template决定的,所以可以在template中进行嵌套
例:
<body>
<div id="app">
<Father></Father>
</div>
</body>
Vue.component('Father',{
template: '<h3> father <Son></Son> </h3>'
})
Vue.component('Son',{
template: '<h3> son </h3>'
})
new Vue({
el: '#app',
})
上面的属于全局注册的组件嵌套
局部注册的组件嵌套
new Vue({
el: '#app',
components: {
'Father': {
template: '<div> father <Son/> </div>',
components: {
'Son': {
template: '<h3> Son </h3>'
}
}
}
}
})
- 为什么还能在components里面写components呢?
就是因为从Vue.extend()继承过来的,所以new Vue里面能写什么这里也能写。要知道这里的components是简写的,之前是标准写法是包括 Vue.extend()的 - 而且全局注册为什么不用这样写
就是因为全局,所以作用域是针对全局的,而局部注册 子组件必须在父组件中注册之后才能在父组件的模板中使用
template外用
<body>
<div id="app">
<Hello></Hello>
</div>
<template id="Hello">
<div class="content">
<ul>
<li><a href="">你好</a></li>
<li><a href="">你好</a></li>
<li><a href="">你好</a></li>
</ul>
</div>
</template>
</body>
<script>
Vue.component('Hello',{
template: '#Hello'
})
new Vue({
el: '#app',
})
</script>
对于这样的template外用,需要在template里面加类名,同时template只能放在实例的作用范围外,否则放在实例里面会被解析,只有放在body那(就是不放在#app里面)才不会被解析
同时template下面的子元素(根元素)只能有一个,否则会报错
<template id="Hello">
<li><a href="">你好</a></li>
<li><a href="">你好</a></li>
<li><a href="">你好</a></li>
</template> //像这样的会报错
组件的data选项
根实例中的data选项是一个对象, 但是组件中的data选项是一个函数, why?
解释:
首先从函数的作用考虑
函数的作用:
1. 函数有独立作用域
2. 函数可以有return 返回值
所以组件的data选项必须有return 返回值, 并且返回值是一个对象
组件的数据在组件的模板中使用
Vue.component('Hello',{
template: '#Hello',
data(){
return {
msg: 'hello 骏哥'
}
}
})