1. 认识组件
- 组件(Component)是 Vue.js 最强大的功能之一。
- 组件可以扩展 HTML 元素,封装可重用的代码。
- 组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用的界面都可以抽象为一个组件树
2. 注册组件
2.1 全局组件
所有vue实例都能用全局组件
2.1.1 注册全局组件的语法
Vue.component(tagName, options)
tagName 为组件名,options 为配置选项。注册后,我们可以使用以下方式来调用组件:
<tagName></tagName>
2.1.2 全局组件实例
<div id="app">
<v-tab></v-tab>
</div>
<script src="js/vue.js"></script>
<script>
// 注册
Vue.component('VTab', {
template: '<h1>自定义tab组件!</h1>'
})
// 创建根实例
new Vue({
el: '#app'
})
</script>
2.2 局部组件
在实例选项中注册局部组件,这样组件只能在这个实例中使用
2.2.1 局部组件实例
<div id="app">
<!-- 使用自定义局部组件 -->
<v-tab></v-tab>
</div>
<script src="js/vue.js"></script>
<script>
var Child = {
template: '<h1>自定义tab组件!</h1>'
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <v-tab> 将只在父模板可用
'VTab': Child
}
})
</script>
3. 组件的应用
3.1 组件应用中的注意事项
- 组件名首字母大写,在模板中应用时要转为小写,如果是两个单词,中间用"-"连接
- template模板中只能有一个根元素
- 子组件中的data必须是一个有返回值的函数
- 特殊标签中组件的使用
有些 HTML 元素,诸如 <ul>
、<ol>
、<table>
和 <select>
,对于哪些元素可以出现在其内部是有严格限制的。而有些元素,诸如 <li>
、<tr>
和 <option>
,只能出现在其它某些特定的元素内部。
<div id="app">
<table>
<tbody>
<!-- tbody的子元素只能是<tr>,这里用<row>就会解析错误 -->
<row></row>
<row></row>
<row></row>
</tbody>
</table>
</div>
</div>
<script src="vue.js"></script>
<script>
const Row = {
template: "<tr>行数据</tr>"
}
const vm = new Vue({
el: '#app',
data: {
},
components: {
Row
}
});
</script>
解决方案: 只需修改模板 (用匹配的标签,添加is属性,指向相应的组件)
<div id="app">
<table>
<tbody>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
<tr is="row"></tr>
</tbody>
</table>
</div>
3.2 组件应用实例
复用计数器组件
<div id="app">
<p>非组件内容</p>
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
<button-counter></button-counter>
</div>
<script src="js/vue.js"></script>
<script>
// 定义一个名为 button-counter 的新组件
Vue.component('ButtonCounter', {
data: function() {
return {
count: 0
}
},
template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>'
})
const vm = new Vue({
el: '#app',
data: {}
});
</script>
4. 组件中的data为什么是一个有返回值的函数
组件中的data写成一个函数,数据以函数返回值形式定义,这样每复用一次组件,就会返回一份新的data,类似于给每个组件实例创建一个私有的数据空间,让各个组件实例维护各自的数据。而单纯的写成对象形式,就使得所有组件实例共用了一份data,就会造成一个变了全都会变的结果。
理解:
<script>
//===================================== data是对象时的复用
// let data = {
// count: 0
// }
// let com1 = {}
// let com2 = {}
// com1.data和com2.data引用同一地址
// com1.data = data;
// com2.data = data;
// com1.data.count = 5;
// console.log(com2.data.count); //5
// =======================================data是函数时的复用
let data = function(){
return {
count: 0
}
}
let com1 = {}
let com2 = {}
console.log(com1 === com2); //false
// data每次执行返回的都是不同的对象(数据相同,地址不同)
com1.data = data();
com2.data = data();
com1.data.count = 5;
console.log(com2.data.count); // 0
</script>