组件的通信

本文详细介绍了Vue中父子组件如何通过props进行数据传递,包括父组件向子组件传递数据和子组件向父组件传递数据的方法及注意事项。此外,还探讨了非父子组件间的通信,如使用事件总线(eventBus)、本地存储和Vuex状态管理。通过实例代码展示了各个通信方式的实现过程。
摘要由CSDN通过智能技术生成

   分两种:

   1)父子如何通信

   2)非父子之间如何通信

   为什么要通信,因为每组件中的data只能在当前使用,所以要用一些通信手段 。

一.父组件向子组件传递数据

1.语法

 

 

 2.props验证

props的值为{}时,可以做props验证.

type(类型) :props做校验时的常见类型:String,Number,Array,Object,Function,Boolean
required(必填项)
validator(验证器)
default(默认值)

 子

 二. 子组件向父组件传递数据

子传父:   
 必须触发事件   
   子组件:通过触发$emit来触发自定义事件    
   父组件:通过触发自定义事件来接收数据
   注意:  父组件中通过触发自定义事件时,传递的参数需要通过$event来传递,但是$event可以省略

1.语法

 2.子传父应用

用户和你的网站进行交互了,会用的多一点。加入购物车/登录/注册

<template>
  
  <div class="box">
      <h4>子传父应用</h4>

      <!-- <div class="mask" v-if="isShow">
            <span>登录成功</span>
      </div> -->

      <v-toast 
        v-if="isShow" 
        @hide="isShow=false"
        :msg="msg"
      ></v-toast>

      <div class="box">
          <h5>登录</h5>
          <!-- <button @click="isShow = true">登录按钮</button> -->
          <button @click="login">登录按钮</button>
          
      </div>
      
      <div class="box">
          <h5>注册</h5>
          <!-- <button @click="isShow = true">注册按钮</button> -->
          <button @click="register">注册按钮</button>
      </div>
      
      <div class="box">
          <h5>加入购物车</h5>
          <button>加入购物车按钮</button>
      </div>

  </div>
</template>

<script>

import vToast from './Toast.vue'

export default {
    data(){
        return {
            isShow:false,
            msg:'加入购物车成功'
        }
    },
    components:{
        vToast
    },
    mounted(){
        
    },
    methods:{
        login(){
            console.log( 'login' );
            this.isShow = true
            this.msg = '登录失败'
        },
        register(){
            console.log( 'register' );
             this.msg = '注册成功'
            this.isShow = true
        }
    }
}
</script>

 子

<template>
  <div>
      <!-- 一个弹框组件 -->
      <div class="mask">
            <span>{{msg}}</span>
      </div>
  </div>
</template>

<script>
export default {
    props:[ 'msg' ],
    mounted(){
        //console.log( 'toast弹框挂载成功了,并开启了一个定时器' );
        setTimeout(()=>{  //箭头函数中的this是上层环境
            console.log( '我要把show改成false' );
            this.$emit( 'hide' )
        },2000)
    }
}
</script>


<style scoped>
.mask{
    width: 100vw;
    height: 100vh;
    position: absolute;
    top:0;
    left: 0;
}
.mask span{
    display: inline-block;
    position:absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50% -50%);
    background-color: rgba(0,0,0,0.6);
    color: #fff;
    padding: 10px 20px;
    border-radius: 20px;
}
</style>

3.父传子总结

父传子,父组件传递数据给子组件,默认是父变,子变;子变,父不变,还报错

直接修改:父变,子变,子变,父变,还不报错 ,传递对象。因为本质上对象是引用类型

间接修改:子组件想要修改父组件的值,使用子传父。$emit

<template>
  <div class="box">
    <h4>父传子,子传父总结</h4>

    <!-- 
        父传子,父组件传递数据给子组件,默认是父变,子变;子变,父不变,还报错 
        直接修改:父变,子变,子变,父变,还不报错 ,传递对象。因为本质上对象是引用类型
        间接修改:子组件想要修改父组件的值,使用子传父。$emit
       -->

    username:{{ username }}
    <hr />
    <input type="text" v-model="username" />
    <hr />
    persons:{{ persons.username }}
    <hr />
    <input type="text" v-model="persons.username" />

    <v-child :username="username" :persons="persons"></v-child>
  </div>
</template>

<script>
import vChild from "./vChild.vue";
export default {
  components: {
    vChild,
  },
  data() {
    return {
      username: "zs",
      persons: {
        username: "ls",
        age: 20,
      },
    };
  },
};
</script>

<style>
</style>

<template>
  <div class="box">
      <h4>child</h4>
      username:{{username}}
      <hr>
      <input type="text" v-model="username">
      <hr>
      persons:{{ persons.username }}
      <hr>
      <input type="text" v-model="persons.username">
  </div>
</template>

<script>
export default {
  props:[ 'username','persons' ]
}
</script>

3.非父子之间组件的通信

eventBus:事件总线 (了解), 子传父的原理其实就是事件总线 。

实现非父子组件通信有三种:
    1.eventBus   前提: A  B需要同时存在
    2.本地存储  localStorage  sessionStorage
    3.vuex(状态管理模式): 重点
    4.cookie/session

index.vue

<template>
  <div class="box">
      <h4>非父子之间的通信</h4>

        <!-- 
            事件总线:eventBus
            事件的订阅与发布:事件的兼听和触发

            谁要数据谁就绑定事件兼听的函数,谁给数据谁就触发事件
            A要B里的数据。A绑定一个事件兼听,B触发A的事件

            步骤:
            1. 在main.js中添加如下代码
                Vue.prototype.$eventBus = new Vue()
                    就相当于一个公共的池子
                
            2. 在任意文件中的this实例上都可以到 this.$eventBus 就可以访问到
                因为每个.vue组件实例对象都继承于Vue构造函数
                但是每个this是当前组件的实例对象,而且每个页面之间是不共享的
            3. A要B里的数据。A绑定一个事件兼听,B触发A的事件
                3.1 A绑定一个事件兼听
                this.$eventBus.$on(事件,事件函数)
                3.2 B触发A中兼听的事件函数,并且可以传参
         -->

      <v-a></v-a>
      <v-b></v-b>
  </div>
</template>

<script>
import vA from './vA.vue'
import vB from './vB.vue'
export default {
    components:{
        vB,
        vA
    },
    mounted(){
        // console.log( this,'index.vue' );
        // console.log( this.$aa,'---aa--' );
        console.log( this.$eventBus,'index.vue' );
    }
}
</script>

<style>

</style>

vA.vue

<template>
  <div class="box">
    <h4>a</h4>
    {{ username }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      username: "鲁肃",
    };
  },
  mounted() {
    //console.log( this.$eventBus,'a.vue' );
    this.$eventBus.$on("aEvent", (e) => {
      console.log("触发了aEvent事件", e);
      this.username = e.username
    });
  },
};
</script>

<style>
</style>

vB.vue

<template>
  <div class="box">
      <h4>b</h4>
      <button @click="bFN">触发A中的事件</button>
  </div>
</template>

<script>
export default {
    methods:{
        bFN(){
           this.$eventBus.$emit('aEvent',{ username:'鲁班' }) 
        }
    }
}
</script>

<style>

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沁沁酱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值