第七章 组件详解
组件的作用是为了代码可复用,提高重用性。在使用组件时可以自定义标签。比如:<Card>、<Row>、<i-col>等。
7.1.2 组件用法
组件需要注册后才能使用。注册分为全局注册和局部注册两种方式。全局注册后,任何Vue实例都可以使用。组件名自定义,最好使用小写加减号的形式命名。要是在父实例使用组件,必须要在实例创建前注册。
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component',{
//选项,需要显示的组件内容
template:'<div>组件内容</div>';
});
var app = new Vue({
el:'#app',
})
</script>
Template的DOM结构必须被一个元素包含,如果不带<div></div>标签是无法渲染的。Vue实例中,使用component选项可以局部注册组件,注册的组件只在该Vue实例下有效。
<div id="app">
<my-component></my-component>
</div>
<script>
var Child = {
template:'<div>组件内容</div>'
}
var app = new Vue({
el:'#app',
components:{
'my-component':Child
}
})
</script>
Vue组件的模板受Html标签的限制,如<table>只允许<td>、<tr>、<th>等表格元素。所以直接在<table>内使用组件时无效的。这时,要使用特殊的is属性来挂载组件。
<div id="app">
<table>
<tbody is="my-component"></tbody>
</table>
</div>
除template选项外,还可以使用其他的选项,比如:data、computed、methods等。但在使用data时,和实例的区别是,data必须是函数,然后将数据return出去。
<div id="app">
<my-component></my-component>
</div>
<script>
Vue.component('my-component',{
//选项,需要显示的组件内容
template:'<div>{{message}}/div>',
data:function(){
return {
message:'组件内容'
}
}
});
var app = new Vue({
el:'#app',
})
</script>
javascript对象是引用关系,所以如果return出的对象引用了外部的一个对象,那这个对象就是共享的,任意一方修改皆会改变。
7.2 使用props传递数据
7.2.1 基本用法
组件不仅仅要把模板内容复用,也需要实现组件间的通信。通常父组件会向子组件传递数据或参数,子组件通过获取父组件的数值不同渲染不同效果。这个正向传递就是通过props实现的。使用props声明需要从父组件中接收的数据,props可以分为字符串数组和对象两种。
<div id="app">
<my-component message="来自父组件的数据"></my-component>
</div>
<script>
Vue.component('my-component',{
props:{'message'},
template:'<div>{{message}}</div>',
});
var app = new Vue({
el:'#app',
})
</script>
Props中声明的数据和组件data函数return的数据主要区别在于props来自父级,而data中是组件自己的数据,作用域是组件本身。这两种数据都可以在模板template及计算属性computed和方法methods中使用。
由于html不区分大小写,当时使用DOM模板时,驼峰命名会被转化为短横分割命名。
当传递的值是动态赋值时,需要使用v-bind来绑定props值,当父组件数值变化时,子组件也会相应改变。
<div id="app">
<input type="text" v-model="parentMessage">
<my-component :message="parentMessage"></my-component>
</div>
<script>
Vue.component('my-component',{
props:['message'],
template:'<div>{{message}}</div>',
});
var app = new Vue({
el:'#app',
data:{
parentMessage:''
}
})
</script>
7.2.2 单向数据流
Vue2.X通过props传递数据是单向的,父组件数值变化可以传递到子组件,但反向则不行。业务中经常会有两种要改变prop的情况。一种是父组件传递初始值进来,子组件将初始值保存起来,在自己的作用域随意修改。这种需要再组件data中声明数据,引用父组件的prop。
注意:在JavaScript中对象和数组是引用类型,指向同一个内存空间,所以当props是对象或者数组时,在子组件内改变是会影响到父组件的。
7.2.3 数据验证
Vue.component('my-component',{
props:{
//数字类型
propA:Number,
//字符串或者数字类型
propB:[String,Number],
//布尔值,如果没有定义,默认true
propC:{
type:Boolean,
default:true,
},
//数字且必传
propD:{
type:Number,
required:true
},
//数组或对象,默认是一个函数返回
propE:{
type:Array,
default:function(){
return [];
}
},
//自定义验证函数
propF:{
validator:function(value){
return value > 10;
}
}
},
});