被问多了,来做个总结。先约定要用到的父子和兄弟组件,接下来只贴出关键部分代码:
//父组件
<template>
<div id="app">
<Son></Son>
</div>
</template>
import Son from './components/son'
export default {
name: 'app',
components: {
Son
}
}
//子组件
<template>
<div>
</div>
</template>
export default {
name: "son",
methods:{
}
}
父子组件通信
父组件向子组件通信
1.父组件通过v-bind绑定属性,向子元素传递
//父组件内
<template>
...
<Son :toSonMsg="toSonMsg"></Son> /*通过绑定属性像子组件传递toSonMsg*/
...
</template>
export default {
...
data(){
return {
toSonMsg: 'hello son'
}
},
...
}
//子组件
<template>
...
<h2>{{toSonMsg}}</h2>
...
</template>
export default {
...
props:{ //子组件通过props属性接收注册父组件传递过来的信息
toSonMsg: String
},
}
2.父组件通过refs属性调用子组件方法
父组件通过refs来获取子组件实例上的信息:
//父组件
<template>
...
<Son ref="son"></Son>
<button @click="doSonMethods">doSonMethods</button>
...
</template>
export default {
...
methods:{
doSonMethods(){
this.$refs.son.changeSomMsg('father come!!!') //调用子组件的changeSomMsg方法
},
},
}
//子组件
<template>
<div>
<h2>{{sonMsg}}</h2>
</div>
</template>
export default {
...
data(){
return {
sonMsg: "i'm son"
}
},
methods:{
changeSomMsg(msg){
this.sonMsg = msg
},
}
}
子组件向父组件通信
1.@事件绑定 + $emit事件触发
//父组件
<template>
...
<Son :toSonMsg="toSonMsg" @getSonMsg="sonCallBack"></Son> //绑定事件
...
</template>
export default {
...
data(){
return {
toSonMsg: 'hello son'
}
},
methods:{
sonCallBack(msg){ //绑定的事件
this.toSonMsg = msg
}
},
}
//子组件
<template>
...
<h2>{{toSonMsg}}</h2>
<button @click="sendFather">send father</button>
...
</template>
export default {
...
props:{
toSonMsg: String
},
methods:{
sendFather(){ //触发绑定的getSonMsg事件
this.$emit('getSonMsg', 'father is get!!')
}
}
}
2.v-bind事件绑定 + props注册调用
//父组件
<template>
...
<Son :toSonMsg="toSonMsg" :getSonMsg="sonCallBack"></Son>
...
</template>
//实例部分同上
//子组件
//template部分同上
export default {
...
props: {
toSonMsg: String,
getSonMsg: Function
},
methods:{
sendFather(){
this.getSonMsg('father is get!!')
}
}
}
3.子组件通过$parent属性获取父组件实例,调用父组件方法
//父组件
<template>
...
<Son ref="son" :toSonMsg="toSonMsg"></Son>
...
</template>
export default {
...
data(){
return {
toSonMsg: 'hello son'
}
},
methods:{
fatherMethods(msg){
this.toSonMsg = msg
},
},
}
//子组件
<template>
<div>
<h2>{{toSonMsg}}</h2>
<button @click="getFather">getFather</button>
</div>
</template>
export default {
...
props: {
toSonMsg: String,
},
methods:{
getFather(){
this.$parent.fatherMethods('do father methods!!!')
},
}
}
父组件和它n层子组件的通信
provide / inject方式(不推荐)
这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
//父组件
<template>
...
<Son></Son>
<button @click="changeMsg">changeMsg</button>
...
</template>
export default {
...
provide(){
return {
msg: this.msg
}
},
data(){
return {
msg: {
value: 'i am from father' //provide 和 inject绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。所以要讲变动的数据写成传入的对象的属性。
}
}
},
methods:{
changeMsg(){
this.msg.value = 'father change!'
}
}
}
//子组件
<template>
...
<h2>{{msg.value}}</h2>
...
</template>
export default {
...
inject: ['msg']
}
兄弟组件通信方式
先要new一个vue的实例当作他们之间的桥,通过新的实例上的on和emit方法进行通信。
//son和son1是兄弟组件,我们需要在新建的bus.js中暴露一个vue的实例
//bus.js
import Vue from 'vue'
export default new Vue()
//son
<template>
...
<h2>{{sonMsg}}</h2>
...
</template>
import bus from '../assets/js/bus'
export default {
name: "son",
data(){
return {
sonMsg: "i'm son0!"
}
},
created(){
bus.$on('changMsg', msg=>{ //监听changMsg事件
this.sonMsg = msg
})
},
}
//son1
<template>
<button @click="changSon0">changSon0</button>
</template>
import bus from '../assets/js/bus'
export default {
name: "son1",
methods:{
changSon0(){
bus.$emit('changMsg', 'son1 change son0!!!!!!') //触发bus上的changMsg事件
}
}
}