vue3API/父组件与之组件的数据传递。defineProps/defineEmits/defineExpose

在 Vue 3 中,父子组件之间的通信是构建交互式应用的基础。主要有两种情况:父组件向子组件传递数据(父传子),以及子组件向父组件发送消息(子传父)。以下是这两种情况的详细说明和示例:

父传子(Props 下传)

步骤

  1. 在父组件中定义数据: 父组件中定义要传递给子组件的数据。

  2. 通过 Props 传递数据: 使用 props 将数据从父组件传递到子组件。

  3. 在子组件中声明 Props: 子组件通过 defineProps 函数声明它期望从父组件接收的 props

示例

父组件

<template>
  <div>
    <ChildComponent :parentData="data" />
  </div>
</template>

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

const data = ref('这是来自父组件的数据');
</script>

子组件

<template>
  <div>
    <p>{{ parentData }}</p>
  </div>
</template>

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

const props = defineProps({
  parentData: String
});
</script>

子传父(Events 上传)

步骤

  1. 在子组件中触发事件: 子组件使用 defineEmits 函数声明它可以触发的事件,并使用 emit 方法触发事件。

  2. 在父组件中监听事件: 父组件通过 v-on@ 指令监听子组件触发的事件,并定义处理函数。

示例

子组件

<template>
  <button @click="sendDataToParent">发送数据到父组件</button>
</template>

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

const emit = defineEmits(['sendData']);

function sendDataToParent() {
  emit('sendData', '这是来自子组件的数据');
}
</script>

父组件

<template>
  <div>
    <ChildComponent @sendData="handleData" />
  </div>
</template>

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

function handleData(data) {
  console.log(data); // 输出:这是来自子组件的数据
}
</script>

另一种方法( defineExpose

子组件中使用 defineExpose

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

const count = ref(0);

function increment() {
  count.value++;
}

// 通过 defineExpose 暴露给父组件或模板引用
defineExpose({
  count,
  increment
});
</script>

父组件中访问子组件暴露的内容

<template>
  <!-- 给子组件设置一个 ref 名称 -->
  <ChildComponent ref="childRef" />
  <button @click="callChildMethod">调用子组件方法</button>
</template>

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

const childRef = ref(null);

// 使用 onMounted 确保子组件已经挂载
onMounted(() => {
  if (childRef.value) {
    console.log('子组件 count:', childRef.value.count); // 访问暴露的 count
  }
});

function callChildMethod() {
  if (childRef.value) {
    childRef.value.increment(); // 调用暴露的 increment 方法
  }
}
</script>
  • 显式暴露defineExpose 允许你显式地选择哪些属性或方法需要暴露给父组件或模板引用,而不是自动暴露所有。
  • 更好的封装:通过 defineExpose,你可以更好地封装组件的内部状态和逻辑,只暴露必要的接口。
  • 类型安全:在使用 TypeScript 时,defineExpose 可以帮助你确保类型正确性,并且可以在开发工具中提供更好的智能提示。

注意事项

  • 生命周期:确保在访问子组件暴露的属性或方法时,子组件已经挂载并且相应的数据或方法已经初始化。
  • 响应性:暴露的响应式状态(如 ref 或 reactive 对象)在父组件中是响应式的,可以直接观察和使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值