Vue组件之间的通信实例归纳

91 阅读1分钟

开发中经常会遇到组件间需要进行通信的场景,在这里做一个详细的归纳。

父子组件之间的通信

最常见的是父子组件之间的通信,也是通信中较简单的一类。通信分为两种情况:【父组件向子组件通信】和【子组件向父组件通信】

子组件接收父组件的值-props

父组件-communication.vue

<template>
  <div class="father">
    这是父组件<br />
     <!-- v-bind(:)前者自定义名称便于子组件调用,后者要传递的数据名-->
    <child :fatherData="fatherData"></child>
  </div>
</template>
 <script>
import child from '../components/child.vue';
export default {
  components:{
    child
  },
  data() {
    return{
      fatherData:'我是父组件',
    }
  }
} 
</script>     

子组件-child.vue

<template>
  <div  class="child">
    这是子组件<br/>
    <div>接受父组件的值---({{ fatherData }})</div>
  </div>
</template>
<script> 
    export default {
        props:['fatherData'],
    }
</script> 

image.png

子组件改变父组件中的值-this.$emit

子组件-child.vue

<template>
 <div  class="child">
   这是子组件<br/>
   <el-button @click="changeFatherData">改变父组件的值</el-button>    
 </div>
</template>
<script>
   export default {
   data(){
       return{
           childMsg:'我是子组件'
       }
   },
   methods:{
       changeFatherData(){
           this.$emit('getChildData',this.childMsg)
       }
   }
}
</script>

父组件-communication.vue

<template>
 <div class="father">
   这是父组件<br />
   <div>接收子组件的值---({{ childData }})</div>
   <!-- v-model(@)-->
   <child  @getChildData = "getChildData" ></child>
 </div>
</template>
<script>
import child from '../components/child.vue';
export default {
 components:{
   child
 },
 data() {
   return{
     childData:""
   }
 },
 methods:{
   getChildData(value) {
     this.childData = value
   }
 }
} 
</script>

QQ录屏20230220144610.gif

父组件调用子组件中的方法-this.$refs

子组件-child.vue

  methods:{
        childMethods(){
          console.log("子组件中的方法被调用啦!");
        }
    }

父组件-communication.vue

<template>
  <div class="father">
    这是父组件<br />
    <el-button @click="changeChildData">调用子组件中的方法</el-button>
    <child ref="child" ></child>
  </div>
</template>
<script>
import child from '../components/child.vue';
export default {
  components:{
    child
  },
  methods:{
    changeChildData(){
      this.$refs.child.childMethods()
    }
  }
} 
</script>

QQ录屏20230220155322.gif

子组件调用父组件中的方法

$parent

父组件-communication.vue

 methods:{
    fatherMethods() {
      console.log("父组件被调用啦!")
    }
  }

子组件-child.vue

<template>
  <div  class="child">
    这是子组件<br/>
    <el-button @click="changeFatherData">调用父组件中的方法</el-button> 
  </div>
</template>
<script>
export default {
    methods:{
        changeFatherData(){
            this.$parent.fatherMethods()
        }
    }
}
</script>

$emit

父组件-communication.vue

<template>
  <div class="father">
    这是父组件<br />
    <child @fatherMethods="fatherMethods" ></child>
  </div>
</template>
  methods:{
    fatherMethods() {
      console.log("父组件被调用啦!")
    }
  }

子组件-child.vue

<template>
  <div  class="child">
    这是子组件<br/>
    <el-button @click="changeFatherData">调用父组件中的方法</el-button>    
  </div>
</template>
<script>
export default {
    props:['fatherMethods'],
    methods:{
        changeFatherData(){
            this.$emit('fatherMethods')
        },
        
    }
}
</script>

QQ录屏20230220190239.gif

兄弟组件之间的通信

父组件作为桥梁

传递值--emit+props

场景:子组件2接收子组件1中的值

子组件1-child1.vue

<template>
  <div  class="child1">
    这是子组件1<br/>
    <el-button @click="changeChild2">给子组件2传值</el-button>
  </div>
</template>
<script>
export default {
    props:['getChildData'],
    data(){
        return{
            childMsg:'我是子组件1'
        }
    },
    methods:{
        changeChild2(){
          this.$emit('getChildData',this.childMsg)
        }
    }
}
</script>

父组件-communication.vue

<template>
  <div class="father">
    这是父组件<br />
    <div class="component">
      <child1  @getChildData = "getChild1Data" ></child1>
      <child2 :child1Data="child1Data"></child2>
    </div>
  </div>
</template>
<script>
import child1 from '../components/child1.vue';
import child2 from '../components/child2.vue';
export default {
  components:{
    child1,
    child2
  },
  data() {
    return{
      child1Data:""
    }
  },
  methods:{
    getChild1Data(value) {
      this.child1Data = value
    }
  }
} 
</script>

子组件2-child2.vue

    <template>
    <div  class="child2">
      这是子组件2<br/>
        <div>接受子组件1的值---({{ child1Data }})</div>
    </div>
  </template>
<script>
  export default {
      props:['child1Data'],
  }
</script>

QQ录屏20230221170204.gif

传递方法--ref+emit

场景:子组件2调用子组件1中的方法

子组件1-child1.vue

  methods:{
      child1Method(){
            console.log("子组件1中的方法被调用啦!");
          }
    }
}

父组件-communication.vue

<template>
  <div class="father">
    这是父组件<br />
    <div class="component">
      <child1  ref="child1" ></child1>
      <child2 @getChild1Method="getChild1Method"></child2>
    </div>
  </div>
</template>
<script>
import child1 from '../components/child1.vue';
import child2 from '../components/child2.vue';
export default {
  components:{
    child1,
    child2
  },
  methods:{
    getChild1Method() {
      this.$refs.child1.child1Method()
    }
  }
} 
</script>

子组件2-child2.vue

<template>
    <div  class="child2">
      这是子组件2<br/>
        <el-button @click="getChild1Methods">调用子组件1中的方法</el-button>
    </div>
  </template>
 <script>
  export default {
      props:['getChild1Method'],
      data(){
          return{
              childMsg:'我是子组件'
          }
      },
      methods:{
        getChild1Methods(){
            this.$emit('getChild1Method');
        } 
      }
  }
  </script>

QQ录屏20230221175456.gif

eventBus

场景:子组件2接收子组件1中的数据

/utils/eventBus.js

import Vue from 'vue'
const eventBus = new Vue()
export default eventBus 

/main.js

import eventBus from './utils/eventBus'
//这个方式可以在任何组件里直接用 this.$EventBus 调用
Vue.prototype.$eventBus = eventBus 

子组件1-child1.vue

<template>
  <div  class="child1">
    这是子组件1<br/>
    <el-button @click="child1Method">给子组件2传值</el-button>
  </div>
</template>
export default {
    data(){
      return {
        num:1
      }
    },
    methods:{
      child1Method(){
        this.$eventBus.$emit('getNum',this.num);
      }
    }
}
</script>

子组件2-child2.vue

<template>
    <div  class="child2">
      这是子组件2<br/>
        <div>接受子组件1的值---({{ num }})</div>
    </div>
</template>
  <script>
  export default {
      data(){
          return{
              num:null
          }
      },
      mounted() {
        this.$eventBus.$on('getNum',(num)=>{
          this.num = num
          console.log(num);
        })
      },
      beforeDestroy(){
        this.$eventBus.$off('getdNum')
      }
  }
  </script>

QQ录屏20230222104932.gif