Vue父子组件传值以及兄弟组件传值

本文详细介绍了Vue中组件间的通信方式,包括父传子、子传父以及兄弟组件间通信。通过props实现父组件向子组件传递数据,使用$emit触发自定义事件实现子组件向父组件传递数据。此外,还展示了如何利用中央事件总线(事件 bus)实现在没有直接父子关系的兄弟组件间通信。文中提供了具体的代码示例,帮助理解Vue组件间数据流动的原理。
摘要由CSDN通过智能技术生成

1. 父传子

首先我们在component里创建一个子组件,然后用props声明他的属性title,其次在我们的父组件中注册子组件并为属性赋值,最后就可以在子组件中使用这个属性了。

// 子组件 ChildComponent.vue
<template>
  <div>
    <h2>{{ title }}</h2>
  </div>
</template>

<script>
export default {
  props: ['title']
}
</script>

<style lang="scss" scoped>
</style>

// 父组件 App.vue
<template>
  <div id="app">
    <child-component :title="parentTitle"></child-component>
  </div>
</template>

<script>
import childComponent from './components/ChildComponent'
export default {
  data() {
    return {
      parentTitle: '父组件的title'
    }
  },
  components: {
    childComponent
  }
}
</script>
<style lang="scss" scoped>
</style>

这样就简单的将父组件的parentTitle传递给了子组件进行显示,然后我们再给props多添加几个数据

// 子组件 ChildComponent.vue
<template>
  <div>
    <h2>{{ title }}</h2>
    <h2>{{ content }}</h2>
    <h2>{{ obj }}</h2>
  </div>
</template>

<script>
export default {
  props: ['title','content','obj']
}
</script>

<style lang="scss" scoped>
</style>
// 父组件 App.vue
<template>
  <div id="app">
    <child-component :title="parentTitle" :content="parentContent" :obj="parentObj"></child-component>
  </div>
</template>

<script>
import childComponent from './components/ChildComponent'
export default {
  data() {
    return {
      parentTitle: '父组件的title',
      parentContent: '父组件的content',
      parentObj: {
      	username: 'zhangsan',
      	password: '123'
    	}
    }
  },
  components: {
    childComponent
  }
}
</script>
<style lang="scss" scoped>
</style>

演示结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jfaixb0k-1618331979119)(/Users/yinlu/Documents/截屏/截屏2021-04-13 下午10.41.06.png)]

2. 子传父

还是构造的上面的ChildComponent.vue子组件和App.vue父组件,需求就是通过点击子组件的button,统计点击数num,修改父组件的parentNum

// 子组件 ChildComponent.vue
<template>
  <div>
    <h2>{{ num }}</h2>
    <button @click="add">点击</button>
  </div>
</template>

<script>
export default {
  props: ['num'],
  methods: {
    add() {
      // 修改父组件中的parentNum
      // 触发自定义事件fn
      this.$emit('fn')
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
// 父组件 App.vue
<template>
  <div id="app">
    <!-- @fn 自定义事件 -->
    <child-component :num="parentNum" @fn="changeNum"></child-component>
  </div>
</template>

<script>
import childComponent from './components/ChildComponent'
export default {
  data() {
    return {
      parentNum: 0
    }
  },
  components: {
    childComponent
  },
  methods: {
    // 在父组件中构建一个修改这个数据的方法
    changeNum() {
      this.parentNum += 1
    }
  }
}
</script>
<style lang="scss" scoped>
</style>

演示结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0eoGDAyq-1618331979121)(/Users/yinlu/Documents/截屏/children1.gif)]

子组件向父组件传值,就是靠$emit() 这个专门用来触发自定义事件的方法,让changeNum这个函数来执行,从而修改父组件中的parentNum,然后我们再传递个参数,比如设置每次点击加10

// 子组件 ChildComponent.vue
<template>
  <div>
    <h2>{{ num }}</h2>
    <button @click="add(10)">点击</button>
  </div>
</template>

<script>
export default {
  props: ['num'],
  methods: {
    add(value) {
      // 修改父组件中的parentNum
      // 触发自定义事件fn
      this.$emit('fn',value)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>
// 父组件 App.vue
<template>
  <div id="app">
    <!-- @fn 自定义事件 -->
    <child-component :num="parentNum" @fn="changeNum"></child-component>
  </div>
</template>

<script>
import childComponent from './components/ChildComponent'
export default {
  data() {
    return {
      parentNum: 0
    }
  },
  components: {
    childComponent
  },
  methods: {
    // 在父组件中构建一个修改这个数据的方法
    changeNum(val) {
      this.parentNum += val
    }
  }
}
</script>
<style lang="scss" scoped>
</style>

演示结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8GyKZvYh-1618331979123)(/Users/yinlu/Documents/截屏/children.gif)]

3. 兄弟组件之间传值

在component文件夹里再创建一个兄弟组件BrotherComponent.vue,然后每个兄弟组件中都有一个button按钮,需求就是,通过点击一个按钮,来改变另一个按钮的背景色

方法一:中央事件总线(这里用这种方式演示)

方法二:Vuex(关于vuex的使用可以移步这里

中央事件总线就相当于新建一个空的vue对象bus,通过bus来发起自定义监听事件,然后在使用emit() 触发该自定义监听事件,并传递相应的参数

// 兄弟组件1 ChildComponent.vue
<template>
  <div>
    <button @click="changeBgc">按钮1</button>
  </div>
</template>

<script>
import bus from './eventBus'
export default {
  data() {
    return {
      newColor: 'green'
    }
  },
  methods: {
    changeBgc() {
      // 触发自定义监听事件
      bus.$emit('changeBgcEvent', this.newColor)
    }
  }
}
</script>

<style lang="scss" scoped>
</style>

// 兄弟组件2 BrotherComponent.vue
<template>
  <div>
    <button :style="{ backgroundColor: bgc }">按钮2</button>
  </div>
</template>

<script>
import bus from './eventBus'
export default {
  data() {
    return {
      bgc: 'red'
    }
  },
  mounted() {
    bus.$on('changeBgcEvent', (value) => {
      this.bgc = value
    })
  }
}
</script>

<style lang="scss" scoped>
</style>

// eventBus.js
import Vue from 'vue'
export default new Vue()

在这里插入图片描述

感谢观看!下期再见!

在这里插入图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Y shǔ shǔ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值