vue3的通信方式

父组件通信给子组件:

  • 项目结构:

  • 父组件:APP.vue内容:
<template>
  <div class="box1">
    <h1>我是父组件</h1>
    <hr />
    <HelloWorld info="我是父组件参数" :money1="money"></HelloWorld>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import HelloWorld from './components/HelloWorld.vue';
const money = ref(10000);
</script>

<style scoped>
.box1{
  background-color: yellowgreen;
}
</style>
  • 子组件HelloWorld.vue中内容:
<template>
  <div class="box">
    <h1>我是子组件</h1>
    <hr />
    {{info}}
    {{money1}}
  </div>
</template>

<script setup lang="ts">
//defineProps是Vue3提供方法,不需要引入直接使用
let props = defineProps(['info','money1']); //数组|对象写法都可以
</script>

<style>
.box{
  background-color: aqua;
}
</style>
  • 运行结果:

必要说明:

<HelloWorld info="我是父组件参数" :money1="money"></HelloWorld>
const money = ref(1000);

父组件这段代码表示,向子组件HelloWorld组件中传入两个属性参数:

  • info属性,内容是静态内容“我是父组件参数”;
  • :money1="money"属性,这种写法使用了Vue.js的指令语法,其中 :v-bind 指令的简写形式。它的作用是将父组件的数据属性 money 的值动态绑定到属性 money1

个人理解:这个代码向子组件传递money1属性,内容是你在父组件新定义一个money变量,这样可以实现父组件money值变化,子组件相应money1值也变化;

子组件传递给父组件:

  • 项目结构:

  • 父组件APP.vue中的内容:
     
<script setup lang="ts">
import { ref } from "vue";
import HelloWorld from "./components/HelloWorld.vue";
const fmsg = ref('')
const num = ref(0)
const fn = (value)=>{
  fmsg.value = value
}
const addEvent = (value)=>{
  num.value += value
}
</script>

<template>
  <div class="f">
    这是父组件:{{fmsg}}
  </div>
  <div class="f">点击子组件按钮,父组件数字会增加:{{ num }}</div>
  <br />
  <HelloWorld @add="addEvent" @msg="fn" />
  
</template>

<style scoped>
.f{
  background-color: hotpink;
  width: 300px;
}
</style>
  • 子组件HelloWorld.vue内容:
<script setup lang="ts">
import { ref,defineEmits } from "vue";
const emits = defineEmits(["msg","add"]);
const mstr = ref("这是子组件信息");
const btn = () =>{
  emits("msg",mstr.value);
  emits("add",1);
}

</script>

<template>
  <div>这是子组件
    <button @click="btn">子组件按钮</button>
  </div>
</template>

<style scoped>
div{
  background-color: aquamarine;
  width: 300px;
}
</style>
  • 运行结果---初始界面:

  • 运行结果---点击子组件按钮:

  • 必要分析:

   HelloWorld.vue:

       使用defineEmits 函数用于声明组件可以向其父组件发送哪些事件,这些事件均是自定义事件;

       使用 defineEmits 函数,你可以定义一个数组,其中包含组件可以触发的所有事件的名称。这些事件名称将作为函数的参数,你可以在组件的方法中使用这些参数来触发相应的事件。

const emits = defineEmits(["msg","add"]);
  const mstr = ref("这是子组件信息");
  emits("msg",mstr.value);
  emits("add",1);

       在此例中,声明了两个自定义事件属性["msg","add"],采用<dfineEmits类型>emits("自定义事件名称",值)的方式向父组件发送两个自定义事件及相应的值;

   APP.vue:

<HelloWorld @add="addEvent" @msg="fn" />
const fmsg = ref('')
const num = ref(0)
const fn = (value)=>{
  fmsg.value = value
}
const addEvent = (value)=>{
  num.value += value
}

       父组件在引用子组件时,分别用addEvent和fn函数接收来自子组件的时间,其中value是子组件传递过来的值-----这样就做到了点击子组件按钮时,运行了父组件的script脚本,实现了信息的传递。

兄弟组件之间的通信:

项目结构:

父组件APP.vue:(通信过程不参与)

<script setup lang="ts">
import { ref } from "vue";
import brotherA from './components/brotherA.vue'
import brotherB from './components/brotherB.vue'

</script>

<template>
  <div class="k">
    这是父组件
    <br><br>
  <div class="f">
    <brotherA />
  </div>
  <br>
  <div class="m">
    <brotherB />
  </div>
</div>
</template>

<style scoped>
.f{
  background-color: hotpink;
  width: 300px;
}
.m{
  background-color: blueviolet;
  width: 300px;
}
.k{
  background-color: aqua;
  width: 300px;
  height: 300px;
}
</style>

兄弟组件brotherA.vue:

<template>
    这是兄弟组件AAA  
    <button @click="btnA">这是A的按钮</button>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import bus from './bus'
const strA = ref('这是A的数据')
const btnA = () => {
  bus.emit('theA',strA.value)
}
</script>

兄弟组件brotherB.vue:

<template>
    这是兄弟组件BBB:{{bstr}}
</template>

<script lang="ts" setup>
import {ref,onMounted} from 'vue';
import bus from './bus'
const bstr = ref('')

// 使用 onMounted 生命周期钩子来监听事件总线的变化
onMounted(()=>{
    bus.on('theA',(res:string) =>{
        bstr.value = res
    })
})
</script>

事件总线bus.ts:

// 导入 mitt 库,用于创建事件发射器
import mitt from 'mitt';

// 创建一个事件发射器实例
const bus = mitt();

// 导出事件发射器实例,供其他模块使用
export default bus;

运行结果---未点击按钮:

运行结果---点击按钮:

必要分析:

      过程中使用了一个事件总线实例bus的充当通信的中间节点,兄弟组件brotherA.vue将信息传入bus中,再由其兄弟节点brotherB.vue从bus中接收该信息。

      注:本例是vue3 + ts 语法;vue2+js 语法则是定义Vue实例,具体情况请自行查阅; 

// 触发名为 'theA' 的自定义事件,并传递 strA.value 作为事件参数
bus.emit('theA', strA.value);
// 在组件挂载后,监听事件总线 bus 上的 'theA' 事件
onMounted(()=>{
    // 当 'theA' 事件被触发时,执行回调函数
    bus.on('theA',(res:string) =>{
        // 将事件传递的字符串 res 赋值给响应式数据 bstr
        bstr.value = res
    })
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值