Skip to content

组件通信——props

1. 父传子

  • 在父组件使用使用 v-bind 给子组件传数据
vue
<script lang="ts" setup>
import {ref} from 'vue';

const data = ref('Hello, World!');
</script>

<template>
  <ChildComponent 
    :data="data"
  />
</template>
  • 在子组件通过 defineProps 接收父组件传来的数据
vue

<script lang="ts" setup>
// 接收来自父组件的数据
const props = defineProps<{
  data: string;
}>();

// 使用数据
console.log(props.data);

// 在template里可以直接用data变量
</script>

<template>
  <div>{{ data }}</div>
</template>

2. 子传父

在 Vue 3 中,子组件向父组件传递数据通常通过 $emit 来实现。 具体流程如下:

  • 在子组件中使用 defineEmits 来定义需要向父组件传递的事件
vue
<script lang="ts" setup>
import { defineEmits } from 'vue';
// // 定义一个事件发射器
// const emit = defineEmits(['updateData']);

// 标注类型
interface Emits {
  (event: 'updateData', message: string): void;    // 括号里的两个参数是事件名和事件参数类型,:void 表示没有返回值
  (event: 'otherEvent', data: any): void;   // 可以定义多个事件
}

const emit = defineEmits<Emits>();

// 当某个条件满足或用户交互时触发此函数
function sendDataToParent() {
  const message = 'Hello from Child!';
  // 通过事件发射器发射 'updateData' 事件,并附带数据
  emit('updateData', message);
}
</script>

<template>
  <button @click="sendDataToParent">Send to Parent</button>
</template>

在这个例子中,我们创建了一个按钮,当点击按钮时会调用 sendDataToParent 函数,该函数会通过 emit 发射一个名为 updateData 的事件,并且携带一条消息作为参数。

  • 在父组件中监听子组件发出的 updateData 事件,并处理接收到的数据。
vue

<script lang="ts" setup>
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';

const parentData = ref('');
// 定义一个处理函数,用于接收子组件发出的 updateData 事件
function handleUpdateData(message: string) {
  parentData.value = message;
  console.log(message);
}
</script>

<template>
  <ChildComponent @updateData="handleUpdateData" />
  <div>
    来自子组件的数据 {{ parentData }}
  </div>
</template>

在这个例子中,我们在父组件中定义了一个 parentData 变量,并监听子组件发出的 updateData 事件,并调用 handleUpdateData 函数处理接收到的消息。

TIP

需要注意的是,defineEmits和defineProps传参还可以写成以下形式:

vue
<script lang="ts" setup>
defineProps({
  text: {
    type: String,   // 这里要用String而不是string,String编译成ts时会自动变成string
    required: false,
    default: '按钮'
  },
  color: {
    type: String,
    required: false,
    default: '#00afee'
  }
})

// 会同等编译成:
defineProps<{
  text?: string
  color?: string
}>()
</script>