Vue 3 中的父子组件传值:详细示例与解析
在 Vue 3 中,父子组件之间的数据传递是一个常见的需求。父组件可以通过 props 将数据传递给子组件,而子组件可以通过 defineProps 接收这些数据。本文将详细介绍父子组件传值的使用方法,并通过优化后的代码示例演示如何实现。
1. 父子组件传值的基本概念
1.1 Props 的作用
- Props 是父组件向子组件传递数据的一种方式。
- 子组件通过
defineProps
接收父组件传递的数据。
1.2 单向数据流
- 数据从父组件流向子组件,子组件不能直接修改父组件传递的数据。
- 如果需要修改父组件的数据,可以通过 事件 通知父组件。
2. 父组件向子组件传递数据
2.1 父组件代码
<template><Person :title="title" :list="persons" />
</template><script lang="ts" setup name="App">
import Person from "./components/Person.vue";
import { reactive } from "vue";
import { type Persons } from "@/types";// 定义响应式数据
const title = "人员列表";
const persons = reactive<Persons>([{ id: "1", name: "John", age: 20 },{ id: "2", name: "Jane", age: 21 },{ id: "3", name: "Jim", age: 22 },
]);
</script><style>
/* 全局样式 */
</style>
2.2 代码解析
-
传递数据:
- 父组件通过
:title="title"
将title
字符串传递给子组件。 - 通过
:list="persons"
将persons
数组传递给子组件。
- 父组件通过
-
响应式数据:
- 使用
reactive
创建响应式数组persons
。
- 使用
3. 子组件接收数据
3.1 子组件代码
<template><div class="person"><h1>{{ title }}</h1><ul><li v-for="item in list" :key="item.id">{{ item.name }} - {{ item.age }} 岁</li></ul></div>
</template><script setup lang="ts">
import { type Persons } from "@/types";// 接收 props
defineProps<{ title: string; list: Persons }>();
</script><style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}h1 {font-size: 24px;margin-bottom: 20px;
}ul {list-style-type: none;padding: 0;
}li {margin: 10px 0;font-size: 18px;
}
</style>
3.2 代码解析
-
接收数据:
- 使用
defineProps
接收父组件传递的title
和list
。 - 通过泛型
<{ title: string; list: Persons }>
定义 props 的类型。
- 使用
-
渲染数据:
- 在模板中使用
{{ title }}
显示标题。 - 使用
v-for
遍历list
并渲染每个人员的姓名和年龄。
- 在模板中使用
4. 使用 withDefaults
设置默认值
如果父组件没有传递某些 props,我们可以使用 withDefaults
为 props 设置默认值。
4.1 子组件代码(带默认值)
<script setup lang="ts">
import { type Persons } from "@/types";// 接收 props 并设置默认值
withDefaults(defineProps<{ title?: string; list?: Persons }>(), {title: "默认标题",list: () => [{ id: "default-1", name: "默认人员1", age: 18 },{ id: "default-2", name: "默认人员2", age: 19 },],
});
</script>
4.2 代码解析
- 设置默认值:
- 使用
withDefaults
为title
和list
设置默认值。 - 如果父组件没有传递
title
或list
,子组件将使用默认值。
- 使用
5. 完整代码示例
5.1 父组件(App.vue)
<template><Person :title="title" :list="persons" />
</template><script lang="ts" setup name="App">
import Person from "./components/Person.vue";
import { reactive } from "vue";
import { type Persons } from "@/types";// 定义响应式数据
const title = "人员列表";
const persons = reactive<Persons>([{ id: "1", name: "John", age: 20 },{ id: "2", name: "Jane", age: 21 },{ id: "3", name: "Jim", age: 22 },
]);
</script><style>
/* 全局样式 */
</style>
5.2 子组件(Person.vue)
<template><div class="person"><h1>{{ title }}</h1><ul><li v-for="item in list" :key="item.id">{{ item.name }} - {{ item.age }} 岁</li></ul></div>
</template><script setup lang="ts">
import { type Persons } from "@/types";// 接收 props 并设置默认值
withDefaults(defineProps<{ title?: string; list?: Persons }>(), {title: "默认标题",list: () => [{ id: "default-1", name: "默认人员1", age: 18 },{ id: "default-2", name: "默认人员2", age: 19 },],
});
</script><style scoped>
.person {background-color: skyblue;box-shadow: 0 0 10px;border-radius: 10px;padding: 20px;
}h1 {font-size: 24px;margin-bottom: 20px;
}ul {list-style-type: none;padding: 0;
}li {margin: 10px 0;font-size: 18px;
}
</style>
6. 总结
-
父子组件传值:
- 父组件通过
props
向子组件传递数据。 - 子组件通过
defineProps
接收数据。
- 父组件通过
-
默认值:
- 使用
withDefaults
为 props 设置默认值。
- 使用
-
单向数据流:
- 数据从父组件流向子组件,子组件不能直接修改父组件的数据。
通过本文的介绍和优化后的代码示例,希望你能更好地理解 Vue 3 中父子组件传值的使用方法,并在实际项目中灵活运用!