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>
相关推荐
子兮曰4 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰4 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万4 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝4 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
A黄俊辉A4 天前
uniapp webview中实现 app和内嵌的H5双向通信
vue.js·json
三十而立洋4 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁4 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄4 天前
JavaScript 隐式全局变量解析
javascript
honkun64 天前
vue 表格组件 vxe-table 配置 ajax 请求自动加载数据与表单查询
vue.js·vxe-table
kybs19914 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net