Vue3组件通信方式

本文详细介绍了Vue.js中props、自定义事件、全局事件总线mitt、v-model、useAttrs、ref、$parent以及provide和inject等关键概念,展示了它们在组件间通信中的应用和作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1、props(父传子)

//父组件中传递
<childComponent fatherValue1="父组件需要传递的值1" :fatherValue2="父组件需要传递的值2"></childComponent>
//子组件中接收
let props=defineProps(['fatherValue1','fatherValue2'])

2、自定义事件(子传父)

//子组件中传递,在子组件的点击事件中触发自定义事件
let $emit=defineEmit(['事件类型']])//返回的是一个函数
$emit('事件类型','参数1','参数2')//第一个参数为事件类型,第二个、第n个参数

//父组件中接收
<childComponent @'事件类型'='handle'></childComponent>
const handle=('参数1','参数2')=>{
}

3、全局事件总线(mitt)

import  mitt from 'mitt'
const $bus=mitt()
export default $bus

组件A代码(发布者):

<button @click='handler'></button>
const handle=()=>{
    $('bus').emit('事件类型','传递参数1','传递参数2')
}

组件B代码(订阅者):

//$bus.on绑定事件(用于接收值)
//$bus.emit触发事件(发送值)
onMounted(()=>{
    $bus.on('事件类型',('接收参数1','接收参数2')=>{
            
    })    
})

4、v-model

  • 可搜集表单数据,数据双向绑定 实现组件之间通信
  • 可实现父子组件数据同步(props+自定义事件)
//父组件中
//v-model相当于给子组件传递props[modelValue]
//相当于给子组件绑定了自定义事件update:modelValue
//可绑定多个v-model ,相当于绑定了两个自定义事件update:pageNo,update:pageSize
<child v-model="money" v-model:pageNo="page" v-model:pageSize="pageSize" >

//子组件中
let props=defineProps(["pageNo","pageSize"])
let $emit=defineEmits(['update:pageNo','update:pageSize'])

5、useAttrs

  • 可以接受父组件传过来的属性字段,事件、自定义事件
  • 如果defindProps接收了,useAttrs就接收不到了
<template>
  <div>
    <ChildComponent class="custom-class" custom-attr="hello" @custom-event="handleCustomEvent" />
  </div>
</template>

<script>
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  methods: {
    handleCustomEvent(msg) {
      console.log('父组件接收到自定义事件:', msg);
    }
  }
};
</script>

<template>
  <div>
    <p>Custom Attr: {{ attrs.customAttr }}</p>
    <button @click="emitCustomEvent">触发自定义事件</button>
  </div>
</template>

<script>
import { useAttrs } from 'vue';

export default {
  setup() {
    const attrs = useAttrs();

    const emitCustomEvent = () => {
      attrs['onCustom-event']('来自子组件的消息');
    };

    return {
      attrs,
      emitCustomEvent
    };
  }
};
</script>

6、ref和$parent

  • ref:获取真实的dom节点,可获取子组件实例对象,前提是子组件的数据需要对外暴露(defindExpose)
  • parent:可以在子组件中或父组件实例 在子组件的点击事件函数里面注入($parent)

使用 ref
子组件中

<template>
  <div>
    <button @click="sendMessageToParent">发送消息给父组件</button>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const message = ref('这是一条来自子组件的消息');

    // 暴露子组件的数据或方法,以便父组件通过 ref 访问
    defineExpose({
      message,
      sendMessageToParent: () => {
        // 触发自定义事件
        console.log('子组件发送消息');
      }
    });

    return {
      message
    };
  }
});
</script>

父组件中

<template>
  <div>
    <ChildComponent ref="childRef" />
    <button @click="receiveMessageFromChild">接收子组件的消息</button>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const childRef = ref(null);

    onMounted(() => {
      // 访问子组件暴露的数据或方法
      console.log(childRef.value.message);
    });

    const receiveMessageFromChild = () => {
      // 从子组件接收消息
      console.log('父组件接收到的消息:', childRef.value.message);
      childRef.value.sendMessageToParent();
    };

    return {
      childRef,
      receiveMessageFromChild
    };
  }
};
</script>


使用 $parent
子组件中

<template>
  <div>
    <button @click="sendMessageToParent">发送消息给父组件</button>
  </div>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const message = ref('这是一条来自子组件的消息');

    // 暴露子组件的数据或方法,以便父组件通过 ref 访问
    defineExpose({
      message,
      sendMessageToParent: () => {
        // 触发自定义事件
        console.log('子组件发送消息');
      }
    });

    return {
      message
    };
  }
});
</script>



父组件中

<template>
  <div>
    <ChildComponent ref="childRef" />
    <button @click="receiveMessageFromChild">接收子组件的消息</button>
  </div>
</template>
<script>
import { ref, onMounted } from 'vue';
import ChildComponent from './ChildComponent.vue';

export default {
  components: {
    ChildComponent
  },
  setup() {
    const childRef = ref(null);

    onMounted(() => {
      // 访问子组件暴露的数据或方法
      console.log(childRef.value.message);
    });

    const receiveMessageFromChild = () => {
      // 从子组件接收消息
      console.log('父组件接收到的消息:', childRef.value.message);
      childRef.value.sendMessageToParent();
    };

    return {
      childRef,
      receiveMessageFromChild
    };
  }
};
</script>


7、provide和inject

Provide 和 Inject 用于祖先组件向后代组件传递数据。

<script>
//祖先组件中
import { provide } from 'vue';

export default {
  setup() {
    provide('key', 'value');
  }
};
</script>


<script>
import { inject } from 'vue';

//在后代组件中
export default {
  setup() {
    const value = inject('key');
    return {
      value
    };
  }
};
</script>


总结

待续···············

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值