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>
相关推荐
peachSoda72 小时前
小程序图片加载优化方案
前端·微信小程序·小程序
Maimai108082 小时前
React Server Components 是什么?一文讲清 CSR、Server Components 与 Next.js 中的客户端/服务端组件
前端·javascript·css·react.js·前端框架·html·web3
肉肉不吃 肉2 小时前
事件循环,宏任务,微任务
前端·javascript
z止于至善2 小时前
Vue ECharts:Vue 生态下的 ECharts 可视化最佳实践
前端·vue.js·echarts·vue echarts
℘团子এ2 小时前
什么是Docker
前端·docker·容器
Software攻城狮2 小时前
【el-table 表格组件 删除标头分割线】
前端·vue.js·elementui
陆康永2 小时前
vue2封装hook函数,可以监听主页面生命周期
前端·javascript·vue.js