父子组件之间通信
最近在学习Vue,组件之间的通信是难点也是重点,所以想稍微总结一下。
父传子:props
由于组件的模板无法使用父组件中的数据,所以需要用到props。
Prop 是你可以在组件上注册的一些自定义特性。当一个值传递给一个 prop 特性的时候,它就变成了那个组件实例的一个属性。在子组件中注册了props后,就能将父组件的数据传进来,我们便能够在组件实例中访问这个值,就像访问 data 中的值一样。
1.
最简单比如想要利用组件展示三个标题:
<div id="blog-post-demo">
<blog-post mytitle="火影忍者"></blog-post>
<blog-post mytitle="死神"></blog-post>
<blog-post mytitle="海贼王"></blog-post>
</div>
JS代码中如果props在全剧组件中注册需要写在实例前,这样实例中才能用到。
Vue.component('blog-post', {
props: ['mytitle'],
template: '<h3>{{ mytitle }}</h3>'
})
new Vue({
el:"#blog-post-demo",
data:{
}
});
这样模板中就能用到div中的mytitle了:
2.
如果是复杂点的数据就希望写在父组件的data中了,注意使用时最好绑定key:
<div id="example">
<blog-post
v-for="post in posts"
v-bind:key="post.id"
v-bind:myname="post.name"
v-bind:mytitle="post.title">
</blog-post>
</div>
Vue.component('blog-post', {
props: ['myname','mytitle'],
template: `<div>
<h3>{{myname}}-{{ mytitle }}</h3>
</div>`
})
new Vue({
el:"#blog-post-demo",
data:{
posts:[
{id:1,title:'火影忍者',name:'1'},
{id:2,title:'死神',name:'2'},
{id:3,title:'海贼王',name:'3'}
]
}
});
结果如下:
将props写在实例中的组件也是可以的:
new Vue({
el:"#example",
data:{
posts:[
{id:1,title:'火影忍者',name:'1'},
{id:2,title:'死神',name:'2'},
{id:3,title:'海贼王',name:'3'}
]
},
components:{
'blog-post':{
props:['myname','mytitle'],
template:`<div>
<h3>{{myname}}-{{ mytitle }}</h3>
</div>`
}
}
});
子传父:$emit
说完在子组件中使用父组件的数据,类似的,有时父组件需要监听子组件的动作,希望子组件的事件能够改变父组件的数据。
这时候需要用到$emit方法,将子组件的事件传给父组件,同时绑定一个方法,这样就能对父组件的数据进行修改。
一个简单的例子:
<div id="example">
<child-cpn @increment="changeTotal" @decrement="changeTotal"></child-cpn>
<h3>点击次数:{{total}}</h3>
</div>
new Vue({
el:'#example',
data:{
total:0
},
methods:{
changeTotal(counter){
this.total=counter//接收子组件传过来的counter值并对data里的total进行修改
}
},
components:{
'child-cpn':{
data(){
return{
counter:0
}
},
methods:{
increment(){
this.counter++;
this.$emit('increment',this.counter)//利用$emit方法将counter传给父组件
},
decrement(){
this.counter--;
this.$emit('decrement',this.counter)
}
},
template:`
<div>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
</div>`
}
}
})
-END-