一文讲解VUE3 defineProps的使用

 更新时间:2025年12月14日 14:31:54   作者:华丽的周遭  
VUE3 defineProps是Vue3组件通信的核心工具之一,通过简洁的语法实现了类型安全响应式绑定与灵活的校验配置,下面就来具体介绍一下,感兴趣的可以了解一下

definePropsVue 3 组合式 APIscript setup语法糖)中用于声明组件 Props编译时宏(Compiler Macro)。它的核心作用是让组件明确接收来自父组件的输入参数(Props),并自动处理 Prop 的响应式绑定、类型校验与默认值。

一、基础概念

  • 适用场景:仅在 <script setup>中使用(Vue 3.2+ 支持),无需手动导入(编译器会自动识别)。
  • 本质:返回一个只读的响应式对象,包含父组件传递的所有 Props(修改 Props 会触发警告,需通过 emit反向通信)。
  • 单向数据流:Props 是“父传子”的单向绑定,子组件不能直接修改 Props,需通过事件通知父组件更新。

二、核心用法

defineProps支持三种声明方式,覆盖从简单到复杂的场景:

1. 数组语法(简单类型)

适用于仅需声明 Prop 名称的场景(无类型校验、默认值或验证):

<script setup>
// 声明两个 Prop:title(字符串)、count(数字)
const props = defineProps(['title', 'count'])
</script>

<template>
  <h1>{{ title }}</h1>
  <p>Count: {{ count }}</p>
</template>

2. 对象语法(带配置项)

适用于需要类型校验、默认值、必填性、自定义验证的场景。对象键为 Prop 名,值为配置对象:

<script setup>
const props = defineProps({
  // 基础类型校验(支持 String/Number/Boolean/Array/Object/Date/Function/Symbol)
  title: {
    type: String,       // 类型(可多个,如 [String, Number])
    required: true,     // 是否必填
    default: 'Default Title' // 默认值(仅当 required: false 时有效)
  },
  // 引用类型默认值需用「工厂函数」返回(避免多实例共享同一引用)
  list: {
    type: Array,
    default: () => []   // 工厂函数返回新数组
  },
  // 自定义验证函数(返回 true 表示合法)
  status: {
    validator(value) {
      return ['active', 'inactive'].includes(value)
    }
  }
})
</script>

配置项说明

选项

类型

说明

type

原生构造函数/数组

校验 Prop 类型(如 String、Number,或多类型 [String, Number])

required

Boolean

是否为必填 Prop

default

任意值/工厂函数

默认值(引用类型必须用工厂函数返回,避免共享)

validator

Function

自定义验证函数(参数为 Prop 值,返回布尔值)

3. TypeScript 类型注解(推荐)

若项目使用 TypeScript,类型注解是最简洁且类型安全的方式(替代对象语法的类型校验)。需配合 defineProps泛型参数使用:

<script setup lang="ts">
// 声明 Props 类型(? 表示可选)
interface Props {
  title?: string
  count: number
  list?: string[]
}

// 用泛型传入类型
const props = defineProps<Props>()
</script>

添加默认值

若需给 TS 类型的 Prop 设置默认值,需配合 withDefaults辅助函数(Vue 3.2+ 支持):

<script setup lang="ts">
interface Props {
  title?: string
  count?: number
  list?: string[]
}

// withDefaults 接收 defineProps 的结果 + 默认值对象
const props = withDefaults(defineProps<Props>(), {
  title: 'Hello Vue',
  count: 0,
  list: () => ['a', 'b'] // 引用类型仍需工厂函数
})
</script>

三、关键特性

1. 响应式访问

defineProps返回的对象是响应式的,可直接在模板或脚本中使用:

<script setup>
const props = defineProps({ msg: String })
console.log(props.msg) // 响应式值(父组件修改时会更新)
</script>

⚠️ 注意不要直接解构 Props(会丢失响应性)!若需解构,需用 toRefstoRef转换:

<script setup>
import { toRefs, toRef } from 'vue'

const props = defineProps({ msg: String, count: Number })

// 正确:保持响应性
const { msg } = toRefs(props) 
const countRef = toRef(props, 'count') 

// 错误:直接解构会失去响应性
// const { msg, count } = props 
</script>

2. 动态 Props

父组件传递的 Prop 若为响应式数据(如 ref/reactive),子组件通过 defineProps接收后会自动同步更新:

<!-- 父组件 -->
<script setup>
import { ref } from 'vue'
const parentMsg = ref('Hello from Parent')
</script>
<template>
  <Child :msg="parentMsg" />
  <button @click="parentMsg = 'Updated'">Change</button>
</template>

<!-- 子组件 -->
<script setup>
const props = defineProps({ msg: String })
</script>
<template>
  <p>{{ msg }}</p> <!-- 点击按钮后会更新为 "Updated" -->
</template>

3. 透传 Attributes(v-bind="$attrs")

未被 defineProps声明的 Prop 会被归为透传 Attributes(如 classstyle或自定义未声明的 Prop),可通过 $attrs访问或自动绑定到根元素:

<script setup>
defineProps(['title']) // 仅声明 title
</script>
<template>
  <!-- 未声明的 Prop(如 class、data-id)会自动绑定到 div -->
  <div class="box" data-id="123">{{ title }}</div>
</template>

若需手动控制透传,可使用 useAttrs()(组合式 API):

<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs() // 包含所有透传 Attributes
</script>

四、常见误区与最佳实践

  • 不要在非 <script setup>中使用definePropsscript setup的专属宏,普通 <script>需用 export default { props: {} }(Vue 2 风格)。
  • 引用类型默认值必须用工厂函数:如 default: () => ({})而非 default: {}(否则所有组件实例共享同一对象)。
  • 优先用 TypeScript 类型注解:比对象语法更简洁,且能享受 TS 的类型提示与校验。
  • 避免直接修改 Props:如需修改,应通过 emit触发父组件的事件(如 @update:count="val => count = val")。

五、与 Vue 2 的区别

Vue 2 中用 export default { props: {} }声明 Props,而 Vue 3 的 defineProps编译时优化(无运行时开销),且更贴合组合式 API 的风格。

总结

defineProps是 Vue 3 组件通信的核心工具之一,通过简洁的语法实现了类型安全响应式绑定灵活的校验配置

到此这篇关于一文讲解VUE3 defineProps的使用的文章就介绍到这了,更多相关VUE3 defineProps使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何解决Vue请求接口出现跨域问题Access-Control-Allow-Origin

    如何解决Vue请求接口出现跨域问题Access-Control-Allow-Origin

    这篇文章主要介绍了如何解决Vue请求接口出现跨域问题Access-Control-Allow-Origin,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-10-10
  • vue中防抖和节流的使用方法

    vue中防抖和节流的使用方法

    防抖和节流是我们在开发过程中常用优化性能的方式,可以减少不必要的计算,不浪费资源,只在适合的时候再进行触发计算,这篇文章主要给大家介绍了关于vue中防抖和节流使用的相关资料,需要的朋友可以参考下
    2021-08-08
  • vue代码分割的实现(codesplit)

    vue代码分割的实现(codesplit)

    这篇文章主要介绍了vue代码分割的实现(codesplit),做了代码分割后,会将代码分离到不同的bundle中,然后进行按需加载这些文件,需要的朋友可以参考下
    2018-11-11
  • vue子路由跳转实现tab选项卡

    vue子路由跳转实现tab选项卡

    这篇文章主要为大家详细介绍了vue子路由跳转实现tab选项卡,完成一个简单的tab选项卡布局,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-07-07
  • 详解Vue3中侦听器watch的使用教程

    详解Vue3中侦听器watch的使用教程

    学过 vue2 的小伙伴们肯定学习过侦听器,主要是用来监听页面数据或者是路由的变化,来执行相应的操作,在 vue3里面呢,也有侦听器的用法,功能基本一样,本文就来为大家详细讲讲
    2022-07-07
  • vue3+vite2实现动态绑定图片的优雅解决方案

    vue3+vite2实现动态绑定图片的优雅解决方案

    这篇文章主要为大家详细介绍了vue3+vite2实现动态绑定图片的优雅解决方案,文中的示例代码简洁易懂,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-08-08
  • Vue实现按钮级权限方案

    Vue实现按钮级权限方案

    这篇文章主要介绍了Vue按钮级权限方案,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-11-11
  • vue2中filter()的实现代码

    vue2中filter()的实现代码

    vue2.0里,不再有自带的过滤器,需要自己定义过滤器。下面通过实例代码给大家介绍vue2中filter()的相关知识,感兴趣的朋友一起看看吧
    2017-07-07
  • vue常见的通信方式总结

    vue常见的通信方式总结

    我们日常项目开发中,少不了组件之间的通信,我们可能只知道一些常见的方式比如props,emits,其实,实现组件间的通信有很多种方式,本文就给大家总结一些我们常见的通信方式,需要的朋友可以参考下
    2023-08-08
  • Vue3为什么这么快

    Vue3为什么这么快

    这篇文章主要介绍了Vue3为什么这么快,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09

最新评论