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>
相关推荐
lichenyang4534 分钟前
从 0 新增一个 `has.echo`:我如何理解小程序容器里的 API 调用链路
前端
leptune31 分钟前
Mac 使用 Microsoft Word 批量将 DOCX 转 PDF(保持原排版)
前端
大龄秃头程序员41 分钟前
Flutter 长列表 1 万条滑动卡顿治理:Baseline vs Optimized 可跑 Demo
前端
yingyima44 分钟前
Git 核心命令速查:掌握底层原理与实战技巧
前端
黄林晴44 分钟前
Kuikly 是什么?和KMP有什么关系?
android·前端
HokKeung1 小时前
Git Hooks 和 Husky 怎么选
前端·前端工程化
李明卫杭州1 小时前
Vue 3 响应式三剑客:ref、shallowRef、reactive,你真的用对了吗?
前端
触底反弹1 小时前
🔥 JavaScript this 指向全解析:面试必考的 5 大绑定规则
前端·javascript·面试
Csvn1 小时前
TypeScript 类型守卫的 4 个实战级别:从 `filter(Boolean)` 到自定义类型谓词
前端
骑士雄师2 小时前
langchain:推荐切片策略
服务器·前端·langchain