Vue 3 中的 props:定义、接收和限制

举报
周杰伦本人 发表于 2025/01/22 16:40:56 2025/01/22
219 0 0
【摘要】 Vue 3 中的 props:定义、接收和限制需求导入假设你正在开发一个 Vue 3 项目,需要实现父子组件之间的数据传递。具体需求如下:父组件:父组件中有一个响应式对象 person,包含 name 和 age。父组件需要将 person 的数据传递给子组件 Person。子组件:子组件需要接收父组件传递的 name 和 age 数据。子组件需要展示这些数据,并确保数据的类型安全性和一致性...

Vue 3 中的 props:定义、接收和限制

需求导入

假设你正在开发一个 Vue 3 项目,需要实现父子组件之间的数据传递。具体需求如下:

  1. 父组件
  • 父组件中有一个响应式对象 person,包含 nameage

  • 父组件需要将 person 的数据传递给子组件 Person

  1. 子组件
  • 子组件需要接收父组件传递的 nameage 数据。

  • 子组件需要展示这些数据,并确保数据的类型安全性和一致性。

问题描述

  • 如何在父组件中定义 person 数据,并将其传递给子组件?

  • 如何在子组件中接收并展示这些数据?

  • 如何确保传递的数据符合预期的类型?

  • 如果父组件没有传递某些数据,子组件如何处理默认值?

这就要用到今天的props了。

在 Vue 3 中,props 是父组件向子组件传递数据的重要机制。通过 props,父组件可以将数据传递给子组件,并且可以对这些数据进行类型限制和默认值设置。接下来,我们将详细学习如何在 Vue 3 中使用 props,并结合 TypeScript 来确保数据的类型安全性和一致性。


一、props 的基本用法

(一)定义 props

在子组件中,你可以使用 defineProps 来定义 props 的结构。defineProps 是 Vue 3 提供的一个宏函数,用于声明子组件接收的 props

(二)示例代码

子组件:

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
  </div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue';

const props = defineProps({
  name: String,
  age: Number
});
</script>

(三)解释

  • defineProps:定义子组件接收的 props

  • props:一个对象,包含所有接收的 props


二、父组件传递 props

(一)传递数据

在父组件中,你可以通过子组件的标签传递数据。

(二)示例代码

<template>
  <div>
    <Person :name="person.name" :age="person.age" />
  </div>
</template>

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

const person = reactive({
  name: '张三',
  age: 18
});
</script>

(三)解释

  • reactive:创建一个响应式对象。

  • :name:age:将 person 对象的 nameage 传递给子组件。要注意,使用冒号。:变量名="",变量名前面使用冒号,后面跟的就是表达式。

如果是数组的话,同样的道理:

  1. 父组件
  • 使用 reactive 定义响应式数组 personList

  • 通过子组件的标签传递 personList

<template>
  <div>
    <PersonList :personList="personList" />
  </div>
</template>

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

interface Person {
  id: string;
  name: string;
  age: number;
}

const personList = reactive<Person[]>([
  { id: '001', name: '张三', age: 18 },
  { id: '002', name: '李四', age: 20 },
  { id: '003', name: '王五', age: 22 }
]);
</script>

  1. 子组件
  • 使用 defineProps 定义接收的 props

  • 使用 v-for 遍历数组并展示数据。

<template>
  <div>
    <ul>
      <li v-for="person in personList" :key="person.id">
        <h2>姓名:{{ person.name }}</h2>
        <h2>年龄:{{ person.age }}</h2>
      </li>
    </ul>
  </div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue';

interface Person {
  id: string;
  name: string;
  age: number;
}

const props = defineProps<{
  personList: Person[];
}>();
</script>

当然Person的泛型定义可以提出来,遍历数组用的是v-for,这里key是person的id,如果真正开发的时候没有id的话可以使用index

关键代码:

<li v-for="(person, index) in personList">
    <h2>索引:{{ index }}</h2>
    <h2>姓名:{{ person.name }}</h2>
    <h2>年龄:{{ person.age }}</h2>
</li>

三、限制 props 的类型

(一)使用 TypeScript 限制类型

在子组件中,你可以使用 TypeScript 来限制 props 的类型。这确保了父组件传递的数据符合预期。

(二)示例代码

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
  </div>
</template>

<script setup lang="ts">
import { defineProps } from 'vue';

interface PersonProps {
  name: string;
  age: number;
}

const props = defineProps<PersonProps>();
</script>

(三)解释

  • PersonProps:定义一个接口,约束 props 的结构。

  • defineProps<PersonProps>():使用泛型指定 props 的类型。


四 设置可选

如果是可以可为空,非必传的话,需要在子组件中设置,

import { defineProps } from 'vue';
import { Person } from '@/types';

const props = defineProps<{
  personList?: Person[]; // 数组可为空
}>();

personList?:通过在属性名后添加 ?,标记 personList 为可选。

五、设置默认值

(一)默认值

你可以为 props 设置默认值,以便在父组件没有传递某些 props 时,子组件可以使用默认值。

(二)示例代码

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
  </div>
</template>

<script setup lang="ts">
import { defineProps, withDefaults } from 'vue';

interface PersonProps {
  name: string;
  age: number;
}

const props = withDefaults(defineProps<PersonProps>(), {
  name: '默认姓名',
  age: 0
});
</script>

(三)解释

  • withDefaults:为 props 设置默认值。

  • 默认值对象:一个对象,指定每个 prop 的默认值。

也就是子承父业,父亲没有,只能靠自己的双手赋予了。


六、运行效果

(一)父组件传递数据

<template>
  <div>
    <Person :name="person.name" :age="person.age" />
  </div>
</template>

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

const person = reactive({
  name: '张三',
  age: 18
});
</script>

(二)子组件接收并展示数据

<template>
  <div>
    <h2>姓名:{{ name }}</h2>
    <h2>年龄:{{ age }}</h2>
  </div>
</template>

<script setup lang="ts">
import { defineProps, withDefaults } from 'vue';

interface PersonProps {
  name: string;
  age: number;
}

const props = withDefaults(defineProps<PersonProps>(), {
  name: '默认姓名',
  age: 0
});
</script>

(三)效果

  • 如果父组件传递了 nameage,子组件会显示传递的值。

  • 如果父组件没有传递某些 props,子组件会使用默认值。


七、总结

(一)props 的定义

  • 使用 defineProps 定义子组件接收的 props

  • 使用 TypeScript 接口或类型别名限制 props 的结构。

(二)传递数据

  • 在父组件中通过子组件的标签传递数据。

(三)限制类型

  • 使用 TypeScript 确保父组件传递的数据符合预期。

(四)设置默认值

  • 使用 withDefaultsprops 设置默认值。

(五)最佳实践

  • 类型安全:使用 TypeScript 确保 props 的类型安全。

  • 默认值:为 props 设置默认值,确保子组件的健壮性。

  • 必要性:使用可选属性(?)标记某些 props 为可选。

通过上述内容更好地理解和使用 Vue 3 中的 props。在实际开发中,合理使用 props 可以确保组件之间的数据传递安全、可靠。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。