程序员scholar 程序员scholar
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
首页
  • Java 基础

    • JavaSE
    • JavaIO
    • JavaAPI速查
  • Java 高级

    • JUC
    • JVM
    • Java新特性
    • 设计模式
  • Web 开发

    • Servlet
    • Java网络编程
  • Web 标准

    • HTML
    • CSS
    • JavaScript
  • 前端框架

    • Vue2
    • Vue3
    • Vue3 + TS
    • 微信小程序
    • uni-app
  • 工具与库

    • jQuery
    • Ajax
    • Axios
    • Webpack
    • Vuex
    • WebSocket
    • 第三方登录
  • 后端与语言扩展

    • ES6
    • Typescript
    • node.js
  • Element-UI
  • Apache ECharts
  • 数据结构
  • HTTP协议
  • HTTPS协议
  • 计算机网络
  • Linux常用命令
  • Windows常用命令
  • SQL数据库

    • MySQL
    • MySQL速查
  • NoSQL数据库

    • Redis
    • ElasticSearch
  • 数据库

    • MyBatis
    • MyBatis-Plus
  • 消息中间件

    • RabbitMQ
  • 服务器

    • Nginx
  • Spring框架

    • Spring6
    • SpringMVC
    • SpringBoot
    • SpringSecurity
  • SpringCould微服务

    • SpringCloud基础
    • 微服务之DDD架构思想
  • 日常必备

    • 开发常用工具包
    • Hutoll工具包
    • IDEA常用配置
    • 开发笔记
    • 日常记录
    • 项目部署
    • 网站导航
    • 产品学习
    • 英语学习
  • 代码管理

    • Maven
    • Git教程
    • Git小乌龟教程
  • 运维工具

    • Docker
    • Jenkins
    • Kubernetes
  • 算法笔记

    • 算法思想
    • 刷题笔记
  • 面试问题常见

    • 十大经典排序算法
    • 面试常见问题集锦
关于
GitHub (opens new window)
npm

(进入注册为作者充电)

  • Vue2

  • Vue3

    • 初识Vue3
    • 组合式API
    • Vue3中的data数据
    • vue3 的 script标签
    • setup函数中执行顺序
    • toRefs() 与 toRef()
    • computed()
    • Vue3弱化this
    • watch() 和 watchEffec()
    • define函数用法
    • defineExpose() 和 ref 属性
    • vue.config.js
    • 生命周期
    • Vue3全局API调用
    • 自定义 Hook
    • 传递数据(props)
      • 1. 什么是 props
      • 2. 在 Vue 3 中定义 props
        • 2.1 defineProps 函数
        • 使用字符串数组定义 props
        • 使用对象定义 props 类型
        • 2.2 使用 TypeScript 声明 props
      • 3. 为 props 设置默认值
        • withDefaults 函数
        • 使用withDefaults设置默认值
      • 4. 父组件如何向子组件传递 props
      • 5. 使用 props 的注意事项
        • 5.1 Prop 名字的格式
        • 5.2 静态和动态 props
      • 6. props 的类型校验
        • 示例:props 类型校验
      • 7. 使用对象一次性传递多个 props
      • 8. Prop 名称冲突
      • 9. 使用 props 的最佳实践
      • 10. props 的使用案例
        • 父组件
        • 子组件
    • 路由
    • pinia
    • 组件通信
    • getCurrentInstance() 和 nextTick()
    • Vue3 新组件
  • vue3 + TS 项目集成

  • Vue全家桶
  • Vue3
scholar
2024-08-05
目录

传递数据(props)

前言

props 是 Vue 组件的重要机制,用于父组件向子组件传递数据。在开发组件化应用时,组件之间的通信变得非常重要,而 props 是解决这个问题的主要方式。props 使得父组件能够通过属性传递数据到子组件,子组件通过声明 props 来接收和使用这些数据。

# 1. 什么是 props

props 是 Vue 组件的一种机制,允许父组件向子组件传递数据。子组件声明自己希望接收的 props,然后父组件通过绑定属性来提供这些数据。props 是单向的,这意味着数据只能从父组件流向子组件,子组件不能直接修改父组件传递的 props,否则 Vue 会警告你。这种单向数据流的特性提高了应用的可维护性和代码的可靠性。

示例:

<!-- 父组件 -->
<template>
  <!-- 使用 `:` 绑定 props -->
  <ChildComponent :title="articleTitle" :likes="articleLikes" />
</template>

<script setup>
const articleTitle = "Vue 3 教程";  // 父组件中的数据
const articleLikes = 123;
</script>
1
2
3
4
5
6
7
8
9
10

在这个示例中,title 和 likes 作为 props 从父组件传递给子组件。

# 2. 在 Vue 3 中定义 props

在 Vue 3 中,<script setup> 提供了一种更简洁的方式来定义和使用 props。我们使用 defineProps 函数来声明子组件需要接收的 props。

# 2.1 defineProps 函数

defineProps 是一个宏函数,用于在 <script setup> 中声明组件接收的 props。它返回一个包含所有传入 props 的对象,并可以通过以下几种方式来定义和声明 props。

语法:

const props = defineProps([propName1, propName2, ...])
1

或者:

const props = defineProps({
  propName1: propType1,
  propName2: propType2,
  ...
})
1
2
3
4
5

# 使用字符串数组定义 props

如果只想声明接收的 props 名字,可以使用字符串数组。

<script setup>
const props = defineProps(['title', 'likes']); // 定义接收的 props 名称
console.log(props.title); // 访问传入的 'title'
console.log(props.likes); // 访问传入的 'likes'
</script>

<template>
  <div>
    <h1>{{ props.title }}</h1>
    <p>Likes: {{ props.likes }}</p>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12

# 使用对象定义 props 类型

你也可以通过对象的形式来声明 props 的名称和类型,以确保传入的数据是正确的类型。

<script setup>
const props = defineProps({
  title: String,  // title 是字符串类型
  likes: Number   // likes 是数字类型
});
console.log(props.title); // 访问传入的 'title'
console.log(props.likes); // 访问传入的 'likes'
</script>

<template>
  <div>
    <h1>{{ props.title }}</h1>
    <p>Likes: {{ props.likes }}</p>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2.2 使用 TypeScript 声明 props

如果你在使用 TypeScript,可以直接通过泛型来声明 props 的类型,这样能够提供更强的类型检查。

<script setup lang="ts">
const props = defineProps<{ title: string; likes: number }>(); // 声明 title 为字符串,likes 为数字
console.log(props.title); // TypeScript 会自动提供类型提示
console.log(props.likes);
</script>

<template>
  <div>
    <h1>{{ props.title }}</h1>
    <p>Likes: {{ props.likes }}</p>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12

通过使用 TypeScript 泛型,我们能够让 Vue 的 props 机制更加严格,确保传入的数据是预期的类型,减少运行时错误。

# 3. 为 props 设置默认值

在开发中,父组件有时不会传递所有的 props,为了保证组件可以正常工作,我们可以为 props 提供默认值。Vue 3 提供了 withDefaults() 函数来处理这种情况。

# withDefaults 函数

withDefaults() 用于为 defineProps() 定义的 props 设置默认值。如果父组件没有传递某个 props,则会使用默认值。

const props = withDefaults(defineProps({
  title: String,
  likes: Number
}), {
  title: '默认标题',  // 默认值
  likes: 0           // 默认值
});
1
2
3
4
5
6
7

# 使用withDefaults设置默认值

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

// 使用 withDefaults 设置 props 的默认值
const props = withDefaults(defineProps({
  title: String,
  likes: Number
}), {
  title: '默认标题', // 如果父组件没有传递 title,则使用 '默认标题'
  likes: 0          // 如果父组件没有传递 likes,则使用 0
});
</script>

<template>
  <div>
    <h1>{{ props.title }}</h1>
    <p>Likes: {{ props.likes }}</p>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 4. 父组件如何向子组件传递 props

在父组件中,我们通过 : 语法将数据从父组件传递给子组件。: 代表动态绑定,传递的是一个变量或表达式的结果。

<template>
  <!-- 父组件通过 : 绑定 props -->
  <ChildComponent :title="articleTitle" :likes="articleLikes" />
</template>

<script setup>
const articleTitle = "我的文章"; // 父组件的数据
const articleLikes = 120;
</script>
1
2
3
4
5
6
7
8
9

在子组件中,我们使用 defineProps 函数接收这些 props。

# 5. 使用 props 的注意事项

# 5.1 Prop 名字的格式

在 Vue 中,props 的名字应当使用不同的命名格式,具体取决于你在模板中如何使用:

  • 在模板中:使用 kebab-case(短横线形式)。
  • 在 JavaScript/TypeScript 中:使用 camelCase。

示例:

<!-- 父组件中传递 props,使用 kebab-case -->
<ChildComponent greeting-message="Hello, Vue 3!" />
1
2
// 在子组件中,接收 props 时使用 camelCase
const props = defineProps({
  greetingMessage: String
});
1
2
3
4

# 5.2 静态和动态 props

  • 静态传递 props:直接传递固定值。

    <ChildComponent title="静态标题" />
    
    1
  • 动态传递 props:使用变量或表达式传递动态值。

    <ChildComponent :title="dynamicTitle" />
    
    1

# 6. props 的类型校验

Vue 支持对 props 进行类型检查,可以通过指定类型来限制传入数据的类型。你可以使用多种内置类型进行校验,如 String、Number、Boolean、Array、Object 等,还可以设置默认值和自定义校验函数。

# 示例:props 类型校验

<script setup>
const props = defineProps({
  // title 必须是 String 类型,并且是必须传递的
  title: {
    type: String,
    required: true
  },
  // likes 是 Number 类型,有一个默认值
  likes: {
    type: Number,
    default: 0
  },
  // 使用自定义校验函数
  status: {
    type: String,
    validator(value) {
      // 只允许 'success', 'error', 'warning' 作为有效值
      return ['success', 'error', 'warning'].includes(value);
    }
  }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 7. 使用对象一次性传递多个 props

有时你可能会想要一次性传递多个 props,这时可以使用 v-bind 语法来将一个对象中的所有属性都传递给子组件。

<template>
  <!-- 使用对象绑定多个 props -->
  <ChildComponent v-bind="article" />
</template>

<script setup>
const article = {
  title: "Vue 3 教程",
  likes: 500
};
</script>
1
2
3
4
5
6
7
8
9
10
11

在这个示例中,article 对象中的 title 和 likes 被作为 props 传递给了 ChildComponent。

# 8. Prop 名称冲突

Vue 会自动将 props 名字与 HTML 原生属性进行合并处理,但如果有冲突,Vue 会优先

解析自定义的 props,以确保自定义属性不被覆盖。

# 9. 使用 props 的最佳实践

  1. 使用明确的 props 定义:确保你明确声明了每个 props 的名称、类型和是否为必填项。这样可以提高组件的可维护性和可读性。
  2. 为可选的 props 设置默认值:通过 withDefaults 或默认值机制,为可选的 props 提供默认值,避免组件因未接收到 props 而无法正常工作。
  3. 尽量避免修改 props 的值:props 是只读的,子组件不应该直接修改传入的 props,否则会违反 Vue 的单向数据流原则。

# 10. props 的使用案例

# 父组件

<template>
  <ChildComponent :title="articleTitle" :likes="articleLikes" />
</template>

<script setup>
const articleTitle = "深入了解 Vue 3 的 Props";
const articleLikes = 300;
</script>
1
2
3
4
5
6
7
8

# 子组件

<template>
  <div>
    <h1>{{ title }}</h1>
    <p>Likes: {{ likes }}</p>
  </div>
</template>

<script setup>
const props = defineProps({
  title: {
    type: String,
    required: true // title 是必须传递的
  },
  likes: {
    type: Number,
    default: 0 // 默认值为 0
  }
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

总结

  • props 是 Vue 组件之间数据传递的主要机制,确保组件能够动态接收外部数据。
  • defineProps() 提供了一种简洁的方式来声明子组件接收的 props,并能够通过 TypeScript 进行类型检查,提升了代码的安全性和可维护性。
  • withDefaults() 函数为 props 提供默认值,确保组件在未接收到父组件的数据时依然能够正常工作。
  • Vue 通过 单向数据流 提高了组件的可预测性和稳定性,减少了数据流动中的副作用,使得组件之间的通信更加明确清晰。
编辑此页 (opens new window)
上次更新: 2025/01/31, 00:18:02
自定义 Hook
路由

← 自定义 Hook 路由→

Theme by Vdoing | Copyright © 2019-2025 程序员scholar
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式