Vue深入组件:Props 详解1_vue中的props是什么意思

yumo6662周前 (09-01)技术文章8

Props 是组件之间传递数据的主要方式,父组件通过 props 向子组件传递数据,子组件则需要显式声明接收的 props。本章将从 props 的声明、使用、传递规则到校验等方面,全面解析 Vue 中的 props 机制。

Props 声明

子组件必须显式声明它所接受的 props,这样 Vue 才能区分传入的是 props 还是透传 attribute(透传 attribute 指未被组件声明为 props 的属性,将在后续章节专门讨论)。根据组件是否使用 <script setup>,声明方式有所不同。

基础声明方式

1. 使用 <script setup>时:defineProps()宏

<script setup> 中,Vue 提供了 defineProps() 宏来声明 props,无需导入即可直接使用。声明后会返回一个包含 props 数据的响应式对象。

 <script setup>
 // 以字符串数组形式声明:接收名为 "foo" 的 prop
 const props = defineProps(['foo'])
 
 // 访问 prop 的值
 console.log(props.foo)
 </script>

2. 不使用 <script setup>时:props选项

若未使用 <script setup>,需在组件选项中通过 props 选项声明,同时 setup() 函数会将 props 作为第一个参数传入。

 export default {
   // 以字符串数组形式声明
   props: ['foo'],
   setup(props) {
     // setup 中通过参数访问 props
     console.log(props.foo)
   }
 }

两种方式的本质一致:defineProps() 的参数与 props 选项的值完全等效,最终都会被处理为组件的 props 配置。

对象形式声明(推荐)

除了字符串数组,更推荐使用对象形式声明 props。对象的 key 是 prop 名称,值可以是类型构造函数(用于类型校验)或更详细的校验配置对象

 // 使用 <script setup> 时
 defineProps({
   title: String, // 声明 "title" 为 String 类型
   likes: Number  // 声明 "likes" 为 Number 类型
 })
 
 // 不使用 <script setup> 时
 export default {
   props: {
     title: String,
     likes: Number
   }
 }

对象形式的优势

  • 自带文档:清晰展示每个 prop 的预期类型,便于团队协作。
  • 类型校验:若父组件传递错误类型,Vue 会在浏览器控制台抛出警告,帮助快速定位问题。

TypeScript 类型标注声明

若搭配 TypeScript 使用 <script setup>,可通过类型标注声明 props,语法更简洁,且能享受 TypeScript 的类型检查。

 <script setup lang="ts">
 // 通过类型标注声明:title 和 likes 为可选属性(? 表示可选)
 defineProps<{
   title?: string
   likes?: number
 }>()
 </script>

类型标注不仅支持基础类型,还支持接口、泛型等复杂类型,更符合 TypeScript 项目的开发习惯。关于类型标注的更多细节,可参考 Vue 官方文档的“组件 props 类型标注”章节。

响应式 Props 解构

Vue 的响应系统通过属性访问跟踪状态依赖(例如在计算属性中访问 props.foo 时,foo 会被标记为依赖项,当 foo 变化时重新执行相关逻辑)。因此,解构 props 时需注意响应性的保持。

Vue 3.5+ 对解构的优化

在 Vue 3.4 及以下版本中,若直接解构 props(如 const { foo } = defineProps(['foo'])),foo 会成为一个非响应式的常量,后续 foo 变化时,依赖它的逻辑(如 watchEffect)不会重新执行。

而在 Vue 3.5+ 中,编译器会自动优化:当在同一个 <script setup> 中解构 defineProps 返回的 props 时,会将解构变量自动转换为 props.xxx 的访问形式,从而保持响应性。

 // Vue 3.5+ 中,以下代码会被编译器优化
 const { foo } = defineProps(['foo'])
 
 watchEffect(() => {
   // 实际等价于 console.log(props.foo),foo 变化时会重新执行
   console.log(foo)
 })

解构时的默认值

可通过 JavaScript 原生的默认值语法为解构的 props 设置默认值,尤其适合基于类型标注的 props 声明。

 // 为可选 prop "foo" 设置默认值 "hello"
 const { foo = 'hello' } = defineProps<{ foo?: string }>()

若需在 IDE 中区分解构的 props 和普通变量,Vue 的 VSCode 扩展提供了“解构 props 内联提示”设置,开启后可在解构变量旁显示 props 标识。

解构 props 传递到函数的注意事项

若将解构的 prop 直接传递到 watch 等需要响应式数据源的函数中,会因传递的是“值”而非“响应式引用”导致无法正常工作。

 const { foo } = defineProps(['foo'])
 
 //  错误:传递的是 foo 的当前值,而非响应式数据源
 watch(foo, (newVal) => { ... })

正确做法:将解构的 prop 包装在 getter 函数中,让 Vue 能跟踪到 props 的访问。

 const { foo } = defineProps(['foo'])
 
 //  正确:通过 getter 函数访问 foo,保持响应性
 watch(() => foo, (newVal) => { ... })

同理,当需将解构的 prop 传递到外部函数并保持响应性时,也应使用 getter 包装:

// 外部函数可通过调用 getter 跟踪 prop 变化
useComposable(() => foo)



相关文章

VScode中集成esp8266/32开发环境详解

引言 文章的起点源于一个小伙伴私信我,想了解如何在vscode中直接开发esp8266。vscode其轻便,小巧等优点越来越受各类程序员的喜爱。 前面我分别介绍了如何在Windows中使用msys32...

Windows下VSCode配置C++环境_配置vscode c语言环境

介绍本文介绍了如何在 Windows 10 下使用 VSCode 配置 C/C++ 环境,编译器采用 MinGW-w64(GCC 在Windows 下的支持)主要参考了微软 VSCode 官方文档配置...

VSCode MCP Server:改进开发流程,打造更智能、更能干的AI智能体

作者:Sebastian Petrus | 编译:小兰模型上下文协议 (Model Context Protocol, MCP) 是一种新的开放标准,它帮助 AI 模型使用通用接口与外部工具、数据源和...

VSCODE搭建python开发环境教程_vscode开发python怎么样

一、python 安装官方网站下载适合的软件安装包,右击以管理员权限运行。2选择第一项,将无法选择安装路径,只能使用默认安装路径。我们选择第二项自定义安装即Customize installation...

人生苦短,我要在VSCode里面用Python

轻沉 发自 浅度寺 量子位 出品 | 公众号 QbitAI在程序员圈子里,Visual Studio Code(以下简称VSCode)可以说是目前最火的代码编辑器之一了。它是微软出品的一款可扩展的轻量...

大语言模型学习PYTHONSTARTUP 变量详解及实用指南

一、概述PYTHONSTARTUP 是一个 环境变量,用于指定一个 Python 脚本路径。每当用户启动 交互式 Python 解释器(即 Python REPL,如在终端执行 python 或 py...