定义:
封装了重用代码的自定义HTML标签,通过组件可以实现对HTML标签的扩展.
组件的注册(创建)
全局组件
在全局范围内都可以使用
Vue.component(组件名称, 组件配置)<code> Vue.component('my-component', { // 该组件被使用的时候返回的结构与样式 //template: '<h1>my-component</h1>' template: ` <dl> <dt>teachers.name</dt> <dd>teacher</dd> </dl> ` }); </code>
注意:确保在初始化根实例之前注册组件,否则会报错。
局部组件
只有在注册的某个vue实例中才可以使用
在任意组件配置中的components选项进行设置
components: {组件名称: {组件配置}}<code> // new Vue得到的对象其实就是一个根组件对象 new Vue({ el: '#app', template: '<h1>#app</h1>', data: { teachers: { name: '老师', list: ['莫涛','钟毅','童斌','朱王洁'] }, students: { name: '学生', list: ['张三','李四','王五'] } }, // 复数形式,值是一个对象,在该属性中注册的组件为当前实例可用 components: { component1: { template: '<h1>component1</h1>', // component2只能在component1中使用了,这里不方便演示,需要使用后期插槽来实现 components: { component2: { template: '<h2>component2</h2>', } } } } }); </code>
注意: new Vue得到的对象其实就是一个根组件对象。
组件的使用
通过标签的方式来使用组件:
<组件名称>
写法
推荐的写法:
* 注册的组件名称使用驼峰命名;
* 对应的HTML标签名称不能有大小写之分,会把驼峰转烤串;
Vue.component('myComponent', {...}
,
==> <my-component a="2"></my-component>
组件的配置
template:组件的模板,经过vue解析后会返回一段html代码,并用这段代码覆盖该组件在html中对应的自定义标签;
注意:模板中的布局有且只能有一个顶级。<code> template:` <!--若不写“<div class="miaov-select">”, 这个模版的布局就有两个顶级,这不被允许。--> <div class="miaov-select"> <div class="text">{{val}}</div> <ul class="list"> <li @click="choose(v)" v-for="v in data">{{v}}</li> </ul> </div> `, </code>
props:
- 当外部需要传入数据给组件内部使用的时候,通过Prop来传递
Pro => property - 外部通过使用该组件的标签上的属性来传入数据;
- 内部使用props属性配置来接收;
- 它定义了能够接收的属性名称;
这个组件就能够接收到外部通过属性传入的a属性,和data类似,可以在组件内部使用this.a来访问;
<code> <my-component a="2"></my-component> <script> Vue.component('myComponent', { props: ['a'], template: ` <dl> <dt>{{a}}</dt> <dd>teacher</dd> </dl> ` }); </code>
- 设置接收的外部属性数据,该数据只能使用,不能修改,否则会有警告,因为会导致组件无意之中修改外部数据而导致一些问题出现,如果一个props数据需要修改的话,那么可以把该数据重新赋值给data;
(若外部出入的数据a是对象,在组件内部直接改a,外部数据会被改变,但依旧会出警告。主要原因是由于地址引用,可通过深度克隆,来破坏地址引用;字符串不会这样。)
- 当外部需要传入数据给组件内部使用的时候,通过Prop来传递
data:设置组件内部使用的私有数据,该数据可以使用,也可以修改;
<code> Vue.component('myComponent', { props: ['data'], // 静态数据,一般用来初始化组件内部数据的,如果我们要对数据进行操作,那么最好使用data来设置数据, //data:组件私有数据 //如果一个数据是动态的,并且他也是传递进来的,那么我们可以把这个数据再传递给data // 组件中的data必须是一个函数 //data: { //}, //data: function() { //可以在这里对data数据进行初始化 //return {} //}, data() { return { // props中的数据名和data中的数据不能相同了 _data: this.data } }, </code>
- methods:组件内部使用的方法。
组件通信
父子组件是隔离的
父子通信:数据
- 父->子:prop
- 子->父:event
父到子的数据传递
1.父级通过组件的标签属性进行传值
- 字面量形式
<tag a="1"></tag>
,这个传递进去的值是固定字符串值 - 动态形式:传递的是表达式
- v-bind:数据是单向绑定的,外部数据的变化会影响组件内部值
- v-model:数据是双向绑定的,通过v-model绑定的值,默认是绑定到了props中value属性,我们可以通过组件的另外一个配置项来设置绑定目标:
model: {prop: 'checked'},<tag v-model="v"></tag>
- 字面量形式
2.组件内部是使用props来接收传入的数据,在props中设置接收的数据的属性名称;
- 3.组件内部其他地方通过“this.属性名”来访问对应的值。
子到父的数据传递
事件通知
v-bind:数据变化的时候,触发一个事件,父级在该组件的标签上添加事件监听并绑定对应的方法
<pre> { this.$emit('evname', 变化后的数据); } //父级 <tag @evname="fn"></tag> fn(newValue) { 根据newValue修改父级数据 } </pre>
v-model:数据变化的时候,触发一个事件,这个事件不是随意乱写的,默认是input,我们可以在model选项中进行设置:
model: {prop: ‘checked’, event: ‘change’},
父级也不在需要去单独监听该事件,vue自动会监听对应事件需改对应的值,但还是需要通过一个默认的事件去通知父级:this.$emit('input', 变化后的数据);
。
注意:- 即使我们通过v-model绑定了,但是还是不能直接去改props中的”value”值。
- 一个组件只能有一个v-model。