组件:是html、css、 js等的一个聚合体
为什么要使用组件?
组件化
- 将一个具备完整功能的项目的一部分分割多处使用
- 加快项目的进度
- 可以进行项目的复用
组件创建语法:
Vue.component( 组件名称, 组建的配置项)
组件创建原理:
Vue.component( 组件名称, Vue.extend())
创建vue组件主要使用了Vue.extend( options )函数;
console.log( Vue )
console.log( Vue.extend() )
//通过控制台打印结果,Vue与Vue.extend结果基本相同,所以配置项用法基本相同
举个例子:组建的基本创建
<body>
<div id="app">
<Father></Father>
</div>
<div id="out">
</div>
<Father></Father>
</body>
<scrip>
var Hel = Vue.extend({
template: '<div> 这里是father组件 </div>'//组件的注册
})
Vue.component( 'Father', Hel )
new Vue({
el: '#app'
})
new Vue({
el: '#out'
})
</script>
- 上述例子中:Father就是我们创建的组件;
- 还有一点要说明:组件必须先注册在使用,使用范围在new Vue()实例范围内,在实例范围外无效;
- 注册原因:为了符合 html / html5的规则,所以组件的标签化使用必须注册,说白了就是用来解析这个标签化的组件未html能识别的标签。
组件的命名:
-
一个单词命名时首字母大写,注意不要和原生h5标签重名eg:header、footer等
-
多个单词时,用小写,中间用 - 作为连接符,eg:header-title
-
不能使用大驼峰命名 eg:Header-Title,会被解析成header-title
组件的注册方式:
-
全局注册
- 第一个例子中我们所用的就是全局注册方式,全局注册的组件我们在任何一个Vue实例中都可以使用;
-
局部注册
<body>
<div id="app">
<Father></Father>
</div>
<div id="out">
<Father></Father>
</div>
</body>
<script>
var Hello = Vue.extend({
template:'<div>这是局部组件</div>'
})
new Vue({
el:"#app",
components:({//局部注册组件
'Father': Hello,
})
});
//在#app内注册的组件,#out访问不到
new Vue({
el:"out",
})
</script>
所以,局部注册组件只能在注册实例中有效
以上我们在使用中,都是先定义
我们有一种简写方式,在使用过程中更简便
// 注册组件,传入一个选项对象 (自动调用 Vue.extend)
Vue.component('my-component', { /* ... */ })//{}内自动调用Vue.extend
//eg:简写示例
<script>
Vue.component('Father',{
template:'<p> 这里是全局组件</p>'
});
new Vue({
el:"#app",
components:({
'hello-title':{
template:'<div> 这里是局部注册 </div>'
}
})
})
</script>
另外,我们使用过程中,难免遇到两个组件的嵌套,那组件的嵌套如何使用呢?看下面例子吧
全局嵌套写法
//这里注册了两个全局组件,如何在实例中使用呢
//错误解析嵌套示例
Vue.component('Hello',{
template:'<div>这里是父组件</div>'
});
Vue.component('Hi',{
template:'<em>这里是子组件</em>'
})
new Vue({
el:"#app"
})
//我们应该会想到这样使用
<div id="app">
<Hello>
<Hi></Hi>
</Hello>
</div>
<!-- 这种嵌套写法是错误的,解析到父组件就找不到Son组件了 -->
//正确解析写法:
Vue.component('Hello',{
template:'<div>这里是父组件<Hi></Hi></div>'
});//将子组件写在父组件内,会正确解析
Vue.component('Hi',{
template:'<em>这里是子组件</em>'
})
new Vue({
el:"#app"
})
<div id="app">
<Hello> </Hello>
</div>
<!-- 正确写法:将子组件写在父组件内,解析到父组件后,会继续解析子组件 -->
局部嵌套写法
//局部嵌套也是将子组件写在父组件内,但是是在示例内直接嵌套
new Vue({
el:"#another",
//局部组件的嵌套,父组件内定义子组件
components:{
'Father':{
template:'<div>这里是父组件<Son></Son></div>',
components:{
'Son':{
template:'<p>这里是子组件<Small></Small></p>',
components:{
'Small':{
template:'<span>这里是子组件二代</span>'
},
}
}
}
},
}
})
//使用方式与全局注册相同,解析到父组件后,子组件会继续执行依次解析。
<div id="another">
<Father></Father>
</div>
component组件中is的使用方法
自定义组件在使用过程中可能会受到限制,从而发生解析错误,举个例子来看一下:
<body>
<div id="app">
<table>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
</tr>
<!--插入自定义组件解析出错-->
<Hello></Hello>
<!--使用is属性可以正确解析-->
<tr is="Hello"></tr>>
</table>
</div>
</body>
<script>
new Vue({
el:"#app",
components:{
Hello:{
template:"<tr><td>4</td><td>4</td><td>5</td></tr>"
}
}
})
</script>
由上可以看出,使用is属性可以解决html存在的标签限制问题
列举一下常见限制:
- a标签不能包含其他的交互标签(如按钮,链接);
- ul和ol只能直接包含li;
- select 只能包含option和optgroup;
- table 只能直接包含thead,tbody,tfoot,tr,caption,col,colgroup;
- tr 只能直接包含th和td;
component中template使用
<body>
<div id="app">
<h3> 实例范围内使用template标签 </h3>
<template>
<div>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
</template>
<h3> 使用 hello 组件</h3>
<Hello></Hello>
</div>
<h3> 实例范围外使用template标签 </h3>
<template id="hello">
<div>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
</template>
</body>
<script>
Vue.component('Hello',{
template: '#hello'
})
new Vue({
el: '#app'
})
</script>
上述例子中,我们可直接使用template标签,直接在html文档中书写注册组件模板,但是使用时稍有限制
template使用:
- 1、实例范围内使用
template中的内容被当做一个整体了,并且template标签是不会解析到html结构中的,不适合作为组件注册模板 - 2、实例范围外使用
实例范围外template标签是不会被直接解析的,可以作为组件注册模板 - 3、组件要想使用template使用,我们采用第二种,但是使用第二种template使用后,有个弊端,template标签结构会在html文件中显示
解决: 使用webpack、gulp等工具编译
以上仅为个人理解