Vue基础-13-组件通信

组件通信概念

Vue中我们所有的页面都是基于组件构造出来,组件之间相互嵌套。父组件、子组件、兄弟组件的说法。

再真实业务开发过程中,我们可能会再父组件中获取数据,交给子组件渲染。获取到父组件传递给他的数据,就这种流程称为组件通信

父组件传递数据给子组件,子组件传递数据给父组件

父子组件通信

prop值传递

可以接受外部数据,组件数据由两部分组成,内部data定义,另外一部分就外部props定义

父组件

 
  1. <template>
  2. <div>
  3. <TabA :array="list" index="no1" :idx="1" :boo="true"></TabA>
  4. </div>
  5. </template>
  6. <script>
  7. import TabA from "./TabA.vue"
  8. export default {
  9. data() {
  10. return {
  11. list: [
  12. { id: 1, title: "流行歌曲" },
  13. { id: 2, title: "网络歌曲" },
  14. { id: 3, title: "emo歌曲" },
  15. ],
  16. };
  17. },
  18. components:{
  19. TabA
  20. }
  21. };
  22. </script>
  23. <style>
  24. </style>

子组件代码

 
  1. <template>
  2. <div>
  3. <div class="linebox">
  4. <ul>
  5. <li v-for="item in array" :key="item.id">{{item.title}}</li>
  6. </ul>
  7. <p>{{index}}</p>
  8. <p>{{idx}}</p>
  9. </div>
  10. </div>
  11. </template>
  12. <script>
  13. export default {
  14. // 组件外部数据
  15. props:["array","index","idx"],
  16. // 组件内部数据
  17. data(){
  18. return{
  19. }
  20. }
  21. }
  22. </script>
  23. <style scoped lang="scss">
  24. .linebox{
  25. width: 100px;
  26. height: 100px;
  27. border: 1px solid red;
  28. }
  29. </style>

父组件传递数据的时候,可以动态数据,也可以静态数据。

传递数据的要求数据类型,加上冒号来传递

字符串除外

子组件获取数据

 
  1. props:[变量1,变量2]

prop验证

自己再封装一个组件的时候,接受外部数据,需要对外部数据进行校验,如果按照你的要求来传递数据,默认能完整显示,否则抛出警告,甚至报错

简单的验证

 
  1. export default {
  2. props:{
  3. list:Array
  4. money:Number
  5. }
  6. }

设置数据类型和默认值

 
  1. export default {
  2. props:{
  3. list:{
  4. type:[Array,Number],
  5. default:[]
  6. }
  7. }
  8. }

可以接受多个数据类型,如果外部没有传递采用default默认值,外部传递数据,传递的值来渲染

emit

也是Vue提供的一个函数,可以实现再子组件里面传递参数给父组件

子组件可以调用父组件的提供的一个函数。

父组件定义一个函数

 
  1. methods:{
  2. changePlay(index){
  3. console.log(index);
  4. this.list[index].play = !this.list[index].play
  5. }
  6. }

父组件自定义一个事件,将函数传递过去

 
  1. <TabA :array="list" @wantChangePlay="changePlay"></TabA>

@wantChangePlay:就是自定义的事件,事件名字自己取,子组件调用的时候就用这个名字

子组件调用

 
  1. <div class="linebox" v-for="(item,index) in array" :key="item.id">
  2. <p>{{item.title}}</p>
  3. <p>{{item.play?"正在播放":"暂停播放"}}</p>
  4. <button @click="$emit('wantChangePlay',index)">播放</button>
  5. </div>

子组件通过$emit函数来调用父组件传的事件名字,触发父组件的函数,就可以将参数传递回父组件

父组件完整代码

 
  1. <template>
  2. <div>
  3. <TabA :array="list" index="no1" :idx="1" :boo="true" @wantChangePlay="changePlay"></TabA>
  4. </div>
  5. </template>
  6. <script>
  7. import TabA from "./TabA.vue"
  8. import TabB from "./TabB.vue"
  9. export default {
  10. data() {
  11. return {
  12. list: [
  13. { id: 1, title: "流行歌曲",play:false },
  14. { id: 2, title: "网络歌曲",play:false },
  15. { id: 3, title: "emo歌曲" ,play:false},
  16. ],
  17. };
  18. },
  19. components:{
  20. TabA,TabB
  21. },
  22. methods:{
  23. changePlay(index){
  24. console.log(index);
  25. this.list[index].play = !this.list[index].play
  26. }
  27. }
  28. };
  29. </script>
  30. <style>
  31. </style>

子组件完整代码

 
  1. <template>
  2. <div>
  3. <div class="linebox" v-for="(item,index) in array" :key="item.id">
  4. <p>{{item.title}}</p>
  5. <p>{{item.play?"正在播放":"暂停播放"}}</p>
  6. <button @click="$emit('wantChangePlay',index)">播放</button>
  7. </div>
  8. </div>
  9. </template>
  10. <script>
  11. export default {
  12. // 组件外部数据
  13. props:["array","index","idx"],
  14. // 组件内部数据
  15. data(){
  16. return{
  17. }
  18. }
  19. }
  20. </script>
  21. <style scoped lang="scss">
  22. .linebox{
  23. width: 200px;
  24. height: 200px;
  25. border: 1px solid red;
  26. }
  27. </style>

兄弟组件通信

Vue组件中如果遇到兄弟组件要传递值,目前我们的方案,将子组件的数据传递父组件,让父组件传递另外一个子组件。

如果遇到两个组件他们离得比较远,父组件来实现传值,就比较麻烦

再Vue中提供了事件总线来实现兄弟组件传递值(任何两个组件之间都可以通信)

事件总线原理:

在事件总线中,核心的原理就是一个组件绑定一个监听器。另外一个组件触发这个监听器。实现两个组件之间通信。

比如A组件要传递数据给B组件,B组件首先要在Bus上面绑定一个监听器。A组件来触发这个监听器。

事件总线任何两个组件之间都可以实现参数传递

场景一:A组件传递参数给B组件

bus总线

在项目中创建一个bus.js文件,里面创建Vue对象

 
  1. import Vue from "vue"
  2. const bus = new Vue
  3. export default bus

B组件:

 
  1. <template>
  2. <div>
  3. <h1>b组件</h1>
  4. </div>
  5. </template>
  6. <script>
  7. import bus from "./bus"
  8. export default {
  9. mounted(){
  10. // 在全局对象中(bus)注册一个监听器
  11. // getData代表事件的名字
  12. bus.$on("getData",data=>{
  13. console.log("B组件接受的数据:",data);
  14. })
  15. }
  16. }
  17. </script>
  18. <style>
  19. </style>

A组件:

 
  1. <template>
  2. <div>
  3. <button @click="sendMessage">传递参数给B组件</button>
  4. </div>
  5. </template>
  6. <script>
  7. import bus from "./bus"
  8. export default {
  9. data(){
  10. return{
  11. msg:"蜗牛"
  12. }
  13. },
  14. methods:{
  15. sendMessage(){
  16. // 触发bus里面的某一个监听器
  17. bus.$emit("getData",this.msg)
  18. }
  19. }
  20. }
  21. </script>
  22. <style>
  23. </style>

bus.$on()代表给Vue对象动态绑定事件

bus.$emit()执行绑定的自定义事件,和父组组件传递参数是一样的。

学习Vuex过后,我们还可以用Vuex来进行组件值传递

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值