Vue3父子组件通信方法总结

一、父组件触发子组件方法

  1. 使用 ref 引用

适用场景 :父组件需要直接调用子组件的方法

复制代码
<!-- 父组件 -->
<template>
  <Child ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const childRef = ref(null);

const callChildMethod = () => {
  childRef.value.childMethod();
};
</script>

<!-- 子组件 (Child.vue) -->
<template>
  <div>子组件</div>
</template>

<script setup>
import { defineExpose } from 'vue';

const childMethod = () => {
  console.log('子组件方法被调用');
};

// 暴露方法给父组件
defineExpose({
  childMethod
});
</script>
  1. 使用自定义事件

适用场景 :需要传递参数给子组件方法

复制代码
<!-- 父组件 -->
<template>
  <Child ref="childRef" />
  <button @click="triggerChildEvent">触发子组件事件</button>
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const childRef = ref(null);

const triggerChildEvent = () => {
  childRef.value.$emit('custom-event', { message: 'Hello' });
};
</script>

<!-- 子组件 (Child.vue) -->
<template>
  <div>子组件</div>
</template>

<script setup>
import { onMounted } from 'vue';

const emit = defineEmits(['custom-event']);

onMounted(() => {
  // 监听自定义事件
  emit('custom-event', { message: 'Initial' });
});

// 也可以在子组件内部监听事件
// 注意:Vue 3 中组件实例的 $on 已移除,推荐使用 props 或 provide/inject
</script>

二、子组件触发父组件方法

  1. 使用自定义事件(defineEmits)

适用场景 :子组件向父组件传递事件

复制代码
<!-- 子组件 -->
<template>
  <button @click="triggerParentMethod">触发父组件方法</button>
</template>

<script setup>
const emit = defineEmits(['parent-event']);

const triggerParentMethod = () => {
  emit('parent-event', { data: '子组件数据' });
};
</script>

<!-- 父组件 -->
<template>
  <Child @parent-event="handleParentEvent" />
</template>

<script setup>
import Child from './Child.vue';

const handleParentEvent = (data) => {
  console.log('父组件方法被调用,数据:', data);
};
</script>
  1. 使用回调函数(props)

适用场景 :父组件传递函数给子组件,子组件调用

复制代码
<!-- 父组件 -->
<template>
  <Child :callback="parentMethod" />
</template>

<script setup>
import Child from './Child.vue';

const parentMethod = (data) => {
  console.log('父组件方法被调用,数据:', data);
};
</script>

<!-- 子组件 -->
<template>
  <button @click="callParentMethod">调用父组件回调</button>
</template>

<script setup>
const props = defineProps({
  callback: {
    type: Function,
    default: () => {}
  }
});

const callParentMethod = () => {
  props.callback({ message: '子组件调用' });
};
</script>

三、父组件给子组件传数据

  1. 使用 defineProps

适用场景 :父组件向子组件传递静态或动态数据

复制代码
<!-- 父组件 -->
<template>
  <Child :message="parentMessage" :count="parentCount" />
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const parentMessage = ref('Hello Vue 3');
const parentCount = ref(10);
</script>

<!-- 子组件 -->
<template>
  <div>{{ message }}</div>
  <div>{{ count }}</div>
</template>

<script setup>
import { watch } from 'vue';

const props = defineProps({
  message: {
    type: String,
    default: ''
  },
  count: {
    type: Number,
    default: 0
  }
});

watch(() => props.message, (newVal) => {
  console.log('收到新的消息:', newVal);
});
</script>
  1. 使用 provide/inject

适用场景 :深层组件嵌套时的跨层级数据传递

复制代码
<!-- 父组件 -->
<script setup>
import { ref, provide } from 'vue';
import Child from './Child.vue';

const sharedData = ref('共享数据');

// 提供数据
provide('sharedData', sharedData);
</script>

<!-- 子组件(或深层子组件) -->
<script setup>
import { inject } from 'vue';

// 注入数据
const sharedData = inject('sharedData');

console.log('注入的数据:', sharedData.value);
</script>

四、子组件给父组件传数据

  1. 使用自定义事件(defineEmits)

适用场景 :子组件向父组件传递数据

复制代码
<!-- 子组件 -->
<template>
  <button @click="sendDataToParent">传递数据给父组件</button>
</template>

<script setup>
const emit = defineEmits(['update-data']);

const sendDataToParent = () => {
  emit('update-data', {
    value: '子组件值',
    message: '子组件数据'
  });
};
</script>

<!-- 父组件 -->
<template>
  <Child @update-data="handleUpdate" />
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const parentData = ref(null);

const handleUpdate = (data) => {
  console.log('收到子组件数据:', data);
  parentData.value = data;
};
</script>
  1. 使用 v-model 双向绑定

适用场景 :需要实现父子组件数据双向绑定

复制代码
<!-- 父组件 -->
<template>
  <Child v-model="parentValue" />
  <p>父组件值:{{ parentValue }}</p>
</template>

<script setup>
import { ref } from 'vue';
import Child from './Child.vue';

const parentValue = ref('初始值');
</script>

<!-- 子组件 -->
<template>
  <input v-model="localValue" @input="updateValue" />
</template>

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

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  }
});

const emit = defineEmits(['update:modelValue']);

const localValue = ref(props.modelValue);

watch(() => props.modelValue, (newVal) => {
  localValue.value = newVal;
});

const updateValue = () => {
  emit('update:modelValue', localValue.value);
};
</script>
相关推荐
SendTomo3 小时前
P2P文件传输工具对比:SendTomo vs send.wang
javascript·网络协议·webrtc·html5·p2p
犹豫的果冻布丁4 小时前
从零给 DeepSeek Harness 写一个壁纸皮肤插件(已开源)
前端·后端
漏刻有时5 小时前
数据可视化Three.js 3D 地图实战:单文件原生实现省域区县拉伸建模
前端
会说话的番茄5 小时前
AI 满嘴跑火车怎么办?给它配个"小抄"
前端·aigc
计算机魔术师5 小时前
AI 权力集中辩论实录:从「token 工厂」到「唯一幸存者」
前端
eric-sjq5 小时前
WanlyFrontend 中文声明式前端语言完全指南:让 0.6B 模型写出漂亮网页
前端
Full Stack Developme5 小时前
跨站请求伪造 (CSRF) 是什么 设计及工作原理
前端·okhttp·csrf
SendTomo5 小时前
WebRTC文件互传工具实测对比
javascript·网络·webrtc·html5·p2p
MoSTChillax5 小时前
UI规范设计:从视觉到交互的全面指南
前端·ui·产品经理·设计规范·vibecoding
雪碧聊技术6 小时前
Vue + Element Plus 实现文本溢出显示省略号及悬浮提示
前端·javascript·css·vue.js·文本溢出省略