Vue父子组件和兄弟组件通信

1 篇文章 0 订阅

一、父子组件通信

1、父组件向子组件传值,通过props传值。

父组件代码:

<template>
  <div class="section">
    <child :list="list"></child>
  </div>
</template>
<script>
import child from './child.vue'
export default {
  components: { child },
  data() {
    return {
      list: ['a1', 'b2', 'c3']
    }
  }
}
</script>

子组件的代码(即 child.vue):

<template>
  <div>
    <span v-for="(item, index) in list" :key="index">{{item}}</span>
  </div>
</template>
<script>
export default {
  props: ['list'],//用法一
  /*props:{
  	list:{
  		type:'Array',
  		default:[]
  	}
  }*/ //用法二
}
</script>

props支持的类型有:String、Number、 Boolean、 Array、Object、Function、 Promise

2、子组件向父组件传值,通过$emit 绑定自定义事件

父组件的代码:

<template>
  <div class="section">
    <child :list="list"  @onEmitIndex="onEmitIndex"></child>
    <p>这里是子组件传递:{{chilInfo.item}}-{{chilInfo.index}}</p>
  </div>
</template>
<script>
import child from './child.vue'
export default {
  components: { child },
  data() {
    return {
      chilInfo:{},
      list: ['a1', 'b2', 'c3']
    }
  },
  methods: {
    onEmitIndex(arg) {
      this.chilInfo= arg;
    }
  }
}
</script>

子组件的代码(即 child.vue):

<template>
  <div>
    <button v-for="(item, index) in list" :key="index" @click="emitIndex(index, item)">{{item}}</button>
  </div>
</template>
<script>
export default {
  props: ['list'],
  methods: {
    emitIndex(index, item) {
      this.$emit('onEmitIndex', {index, item})
    }
  }
}
</script>

3、通过ref/refs实现父子组件通信

ref 如果在普通的 DOM 元素上使用,引用指向的就是 DOM 元素;如果用在子组件上,引用就指向组件实例,可以通过实例直接调用组件的方法或访问数据。也算是子组件向父组件传值的一种。

父组件代码:

<template>
  <div>
    <button @click="sayHello">sayHello</button>
    <child ref="childForRef"></child>
  </div>
</template>
<script>
import child from './child.vue'
  export default {
    components: { child },
    data () {
      return {
      }
    },
    mounted() {
      console.log(this.$refs.childForRef.name);
      // this.childForRef.sayHello();
    },
    methods: {
      sayHello() {
        this.$refs.childForRef.sayHello()
      }
    }
  }
</script>

子组件的代码(即 child.vue):

<template>
  <div>child 的内容</div>
</template>
<script>
export default {
  data () {
    return {
      name: '我是 child',
    }
  },
  methods: {
    sayHello () {
      console.log('hello');
    }
  }
}
</script>

4、通过children/parent实现父子组件传值

父组件代码:

 <template>
  <div>
    <div>{{msg}}</div>
    <child></child>
    <button @click="changeA">点击改变子组件值</button>
  </div>
</template>

<script>
import Child from './child'
export default {
  components: { Child },
  data() {
    return {
      msg: 'Welcome'
    }
  },

  methods: {
    changeA() {
      this.$children[0].messageA = '这是新的数据'
    }
  }
}
</script>

子组件的代码(即 child.vue):

<template>
  <div class="com_a">
    <span>{{messageA}}</span>
    <p>获取父组件的值为:  {{parentVal}}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      messageA: '这是老数据'
    }
  },
  computed:{
    parentVal(){
      return this.$parent.msg;
    }
  }
}
</script>

二、兄弟组件通信、跨级组件通信

1、通过eventBus实现兄弟、跨级组件通信
eventBus 又称为事件总线,在 vue 中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所以组件都可以通知其他组件。一般用来兄弟组件和隔代组件传值。

使用eventBus首先需要创建一个事件总线并将其导出
bus.js:
import Vue from ‘vue’
export const bus = new Vue()
发送事件,child1、child2 两个兄弟组件,在 child1.vue 中使用bus.$emit()发送事件。

父组件代码:

<template>
  <div>
    <child1></child1>
    <child2></child2>
  </div>
</template>
<script>
import child1 from './child1.vue'
import child2 from './child2.vue'
export default {
  components: { child1, child2 }
}
</script>

child1.vue代码:

<template>
  <div>
    <button @click="additionHandle">+加法器</button>    
  </div>
</template>
<script>
import {bus} from '@/bus.js'
// console.log(bus)
export default {
  data(){
    return{
      num:1
    }
  },
  methods:{
    additionHandle(){
      bus.$emit('addition', {
        num:this.num++
      })
    }
  }
}
</script>

在 child2.vue 中使用bus.$on()接收事件

<template>
  <div>计算和: <br>child1Num => {{child1Num}}<br>count + child1Num => {{count}}</div>
</template>
<script>
import { bus } from '@/bus.js'
export default {
  data() {
    return {
      child1Num: 0,
      count: 0,
    }
  },
  mounted() {
    bus.$on('addition', arg=> {
      this.child1Num = arg.num;
      this.count = this.count + arg.num;
    })
  }
}
</script>

如果想移除事件的监听, 可以像下面这样操作:

 import { bus } from './bus.js'
bus.$off('addition', {})

2、通过Vuex状态管理实现兄弟、跨级组件通信
vuex的 store.js

import Vue from 'vue'
 import Vuex from 'vuex'
 Vue.use(Vuex)
 const state = {
   // 初始化A和B组件的数据,等待获取
   AMsg: '',
   BMsg: ''
 }
 
 const mutations = {
   receiveAMsg(state, payload) {
     // 将A组件的数据存放于state
     state.AMsg = payload.AMsg
   },
   receiveBMsg(state, payload) {
     // 将B组件的数据存放于state
     state.BMsg = payload.BMsg
   }
 }
 
 export default new Vuex.Store({
   state,
   mutations
 })
然后需要在 main.js 中引入 vuex

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store';

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  components: { App },
  template: '<App/>'
})

父组件代码:

<template>
  <div id="app">
    <child1 />
    <child2 />
  </div>
</template>

<script>
  import child1 from './Child1' 
  import child2 from './Child2' 

  export default {
    name: 'App',
    components: {child1, child2} 
  }
</script>

child1.vue代码:

<template>
 <div id="childA">
   <h1>我是1组件</h1>
   <button @click="transform">点我让2组件接收到数据</button>
   <p>因为你点了2,所以我的信息发生了变化:{{BMessage}}</p>
 </div>
</template>

<script>
 export default {
   data() {
     return {
       AMessage: 'Hello,2组件,我是1组件'
     }
   },
   computed: {
     BMessage() {
       // 这里存储从store里获取的2组件的数据
       return this.$store.state.BMsg
     }
   },
   methods: {
     transform() {
       // 触发receiveAMsg,将1组件的数据存放到store里去
       this.$store.commit('receiveAMsg', {
         AMsg: this.AMessage
       })
     }
   }
 }
</script>

child2.vue代码:

<template>
 <div id="childB">
   <h1>我是2组件</h1>
   <button @click="transform">点我让1组件接收到数据</button>
   <p>因为你点了1,所以我的信息发生了变化:{{AMessage}}</p>
 </div>
</template>

<script>
 export default {
   data() {
     return {
       BMessage: 'Hello,1组件,我是2组件'
     }
   },
   computed: {
     AMessage() {
       // 这里存储从store里获取的1组件的数据
       return this.$store.state.AMsg
     }
   },
   methods: {
     transform() {
       // 触发receiveBMsg,将2组件的数据存放到store里去
       this.$store.commit('receiveBMsg', {
         BMsg: this.BMessage
       })
     }
   }
 }
</script>

除此之外还有prvide、inject等可以实现组件通信,在这就不详细讲解了,有想了解的可以自己查询相关资料了解。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值