欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 财经 > 金融 > vue3中defineProps的使用说明

vue3中defineProps的使用说明

2025/4/19 3:35:29 来源:https://blog.csdn.net/BillKu/article/details/147094990  浏览:    关键词:vue3中defineProps的使用说明

1、数组写法

const props = defineProps(["applyBasicInfo", "operateCommandType"]);

 这是一个非常基础的 Vue props 声明方式,适用于简单场景。以下是详细解释:


📜 代码含义

javascript

const props = defineProps(["applyBasicInfo", "operateCommandType"]);
  • 作用:声明组件接收两个 props(属性)

  • 特点:仅指定 prop 名称,不进行任何类型校验

  • 等价于

    javascript

    defineProps({applyBasicInfo: null,       // 无类型检查operateCommandType: null     // 无类型检查
    })

🔍 关键特性分析

1. 极简声明
  • 只声明 props 的名称(字符串数组)

  • 不校验类型

  • 没有默认值

  • 不强制 required

2. 适用场景
  • 快速原型开发

  • 不需要类型检查的简单组件

  • 临时过渡代码

3. 实际效果

vue

<!-- 父组件 -->
<ChildComponent :applyBasicInfo="任何类型的数据" <!-- 可以是对象、字符串、数字等 -->operateCommandType="任何内容"    <!-- 可以是任意类型 -->
/><!-- 子组件 -->
<script setup>
// 使用时需要自行确保类型正确
console.log(props.applyBasicInfo) // 可能是任意类型
</script>

🆚 与其他声明方式的对比

特性数组写法对象写法(完整)TypeScript 类型写法
类型校验❌ 无✅ Vue 运行时校验✅ 编译时校验
默认值❌ 不能设置✅ 通过 default 设置✅ 通过 withDefaults 设置
必需性控制❌ 默认都是可选✅ 通过 required 控制✅ 通过 ? 符号控制
类型提示❌ 无🟡 基础类型提示✅ 完整类型提示
代码安全性🔴 低(可能运行时出错)🟡 中(有基础校验)🟢 高(编译时拦截错误)

⚠️ 潜在风险示例

vue

<!-- 父组件传递错误类型 -->
<ChildComponent :applyBasicInfo="123"        <!-- 传递数字 -->operateCommandType           <!-- 未传递 -->
/><!-- 子组件使用时 -->
<script setup>
// 可能引发运行时错误
props.applyBasicInfo.name      // 报错:数字没有 name 属性
props.operateCommandType       // 拼写错误也不会警告(正确是 operateCommandType)
</script>

💡 为什么要用这种写法?

  1. 历史兼容:Vue 2 的 props 数组写法在 Vue 3 中仍然可用

  2. 快速开发:节省写类型校验的时间

  3. 简单场景:当 props 类型不重要或可以确定时


🛠️ 如何改进?

基础改进(添加类型校验):

javascript

const props = defineProps({applyBasicInfo: {type: Object,required: true},operateCommandType: {type: String,default: "view"}
});
高级改进(TypeScript):

typescript

interface ApplyBasicInfo {id: number;name: string;
}const props = defineProps<{applyBasicInfo: ApplyBasicInfo;operateCommandType?: string;
}>();

📌 最佳实践建议

  1. 仅用于临时代码:正式项目建议使用完整声明

  2. 配合 JSDoc 使用(如果不用 TypeScript):

    javascript

    /*** @typedef {Object} ApplyBasicInfo* @property {number} id* @property {string} name*/const props = defineProps(["applyBasicInfo", "operateCommandType"]);
  3. 渐进式增强:后续逐步替换为完整声明


这种写法就像骑自行车不戴头盔——简单快捷,但不够安全。建议新手仅在快速验证想法时使用,正式开发中尽量使用更完善的 props 声明方式。

2、 对象写法(纯 JavaScript 项目的写法,运行时 props 声明

const props = defineProps({applyBasicInfo: {type: Object, // 要求必须是 Object 类型required: true // 表示父组件必须传递这个prop,不能与 default 同时使用},operateCommandType: {type: String, // 要求必须是 String 类型default: "info-view" // 表示当父组件没有传递时使用默认值,不能与 required 同时使用}
});
数组简写 vs 对象写法

javascript

复制

// 简写方式(不推荐)
defineProps(['applyBasicInfo', 'operateCommandType'])// vs // 当前对象写法(推荐)
defineProps({applyBasicInfo: { type: Object, required: true },operateCommandType: { type: String, default: "info-view" }
})
特性数组写法对象写法
类型检查❌ 无✅ 基础类型检查
默认值❌ 不可设置✅ 可设置
必填控制❌ 默认全部可选✅ 精确控制
代码安全性🔴 低🟡 中等

这段代码使用 Vue 的 defineProps 方法声明组件需要接收的两个 props(组件参数),并设置了参数的基本验证规则。 

3、 TypeScript 的类型声明写法

3.1、使用标准的PropType进行对象类型定义

import type { PropType } from "vue";
import type { ApplyBasicInfo } from "@/interface";const props = defineProps({applyBasicInfo: {type: Object as PropType<ApplyBasicInfo>, // 使用标准的PropType进行对象类型定义required: true // 表示父组件必须传递这个prop,不能与 default 同时使用},operateCommandType: {type: String,default: "info-view" // 表示当父组件没有传递时使用默认值,不能与 required 同时使用}
});

🔍 关键概念拆解

1. 类型导入部分

typescript

import type { PropType } from "vue";
import type { ApplyBasicInfo } from "@/interface";
  • PropType:Vue 提供的类型工具,用于在运行时声明中指定复杂类型

  • ApplyBasicInfo:自定义的业务数据类型(通常定义在 src/interface.ts 等位置)

  • import type:TypeScript 语法,表示只导入类型信息,不导入实际代码

2. 核心 props 声明

typescript

applyBasicInfo: {type: Object as PropType<ApplyBasicInfo>, // 类型断言required: true
}
  • Object:Vue 的运行时类型校验(基础对象类型)

  • as PropType<ApplyBasicInfo>:类型断言,告诉 TypeScript 这个对象的具体结构

  • 双重效果

    • 运行时:Vue 检查传入的是否为对象

    • 开发时:TypeScript 检查对象是否符合 ApplyBasicInfo 的结构

3. 对比普通对象声明

typescript

// 普通写法(只有 Vue 校验)
applyBasicInfo: {type: Object,  // 只知道是个对象,不清楚具体结构required: true
}// 当前写法(Vue校验 + TS类型)
applyBasicInfo: {type: Object as PropType<ApplyBasicInfo>, // 明确对象结构required: true
}

🛠️ 工作原理图示

mermaid

graph TDA[父组件传递 props] --> B{Vue 运行时校验}B -->|通过| C[组件内使用]B -->|不通过| D[控制台警告]C --> E[TypeScript 类型检查]E -->|类型正确| F[正常开发]E -->|类型错误| G[IDE 提示错误]

💡 为什么要这样写?

优势对比表
特性普通 Object 类型当前写法
代码提示只知道是对象,无具体属性提示✅ 显示 ApplyBasicInfo 的所有属性
重构安全性修改属性时不会报错✅ 修改接口定义会引发相关代码报错
参数校验只校验是否是对象✅ 运行时对象校验 + 类型结构校验
协作效率需要查文档看数据结构✅ 直接通过提示查看数据结构
示例类型定义

typescript

// 假设在 @/interface 中
interface ApplyBasicInfo {id: number;          // 申请IDapplicant: string;   // 申请人姓名status: 'pending' | 'approved'; // 申请状态createTime: Date;    // 创建时间
}

🚀 在组件中的实际使用

智能提示示例

typescript

// 正确使用(有提示)
props.applyBasicInfo.id          // 提示 number 类型
props.applyBasicInfo.applicant   // 提示 string 类型// 错误使用(立即报错)
props.applyBasicInfo.APPlicant   // ❌ 拼写错误提示
props.applyBasicInfo.status = 'rejected' // ❌ 类型不匹配
对应模板使用

vue

<template><!-- 显示申请人信息 --><div>{{ props.applyBasicInfo.applicant }}</div><!-- 根据操作类型显示不同内容 --><div v-if="operateCommandType === 'info-view'">查看模式</div>
</template>

⚠️ 常见错误及解决方案

错误1:未定义接口

typescript

// 错误提示:Cannot find name 'ApplyBasicInfo'
// 解决方案:确保类型文件正确定义并导出
// 在 @/interface.ts 中:
export interface ApplyBasicInfo { ... }
错误2:错误类型传递

vue

<!-- 父组件传递错误数据结构 -->
<MyComponent :apply-basic-info="{ id: '100' }" />
<!-- 错误:id 应该是 number -->
错误3:缺少必要属性

typescript

// 组件内使用时
const submit = () => {console.log(props.applyBasicInfo.createTime) // 如果接口中有该属性
}
// 当父组件传递的对象缺少 createTime 时,TS 会报错

🆚 不同技术栈的写法对比

场景JavaScript 写法TypeScript 基础写法当前进阶写法
props 类型type: Objecttype: ObjectObject as PropType<T>
代码提示显示 Object 类型显示具体接口属性
类型安全
维护成本高(需口头沟通数据结构)中(需查看接口定义)低(直接提示数据结构)

📌 最佳实践建议

  1. 接口定义规范

    • 在 src/types 或 src/interface 目录统一管理类型

    • 为每个接口添加文档注释

      typescript

      interface ApplyBasicInfo {/*** 申请的唯一标识* @example 123456*/id: number;
      }
  2. props 校验增强

    typescript

    applyBasicInfo: {type: Object as PropType<ApplyBasicInfo>,required: true,validator: (value: ApplyBasicInfo) => {return !!value.id // 添加自定义校验逻辑}
    }
  3. 默认值处理技巧

    typescript

    // 对于复杂对象,建议提供默认值函数
    applyBasicInfo: {type: Object as PropType<ApplyBasicInfo>,default: () => ({ id: 0, applicant: '', status: 'pending' })
    }

这种写法是 Vue 3 项目中平衡类型安全和开发效率的典型实践,既能享受 TypeScript 的类型提示优势,又保留了 Vue 原有的 props 校验机制,特别适合中大型项目维护使用。

3.2、混合写法(结合了 Vue 的运行时 props 校验和 TypeScript 类型提示的混合写法)

import type { ApplyBasicInfo } from "@/interface";const props = defineProps({applyBasicInfo: {type: Object as () => ApplyBasicInfo, // 使用箭头函数返回类型required: true // 表示父组件必须传递这个prop,不能与 default 同时使用},operateCommandType: {type: String,default: "info-view" // 表示当父组件没有传递时使用默认值,不能与 required 同时使用}
});

这是一个结合了 Vue 的运行时 props 校验和 TypeScript 类型提示的混合写法代码,特别适用于 Vue 3 + TypeScript 项目。以下是逐层解析:


📜 代码结构解析

typescript

import type { ApplyBasicInfo } from "@/interface"; // 导入类型const props = defineProps({applyBasicInfo: {type: Object as () => ApplyBasicInfo, // 核心类型声明required: true},operateCommandType: {type: String,default: "info-view"}
});

🔍 关键部分详解

1. 类型导入

typescript

import type { ApplyBasicInfo } from "@/interface";
  • 作用:导入自定义类型(通常定义在 src/interface.ts 或类型声明文件中)

  • 示例类型定义

    typescript

    // 假设在 @/interface 中
    interface ApplyBasicInfo {id: number;name: string;status: 'pending' | 'approved';createTime: Date;
    }
2. defineProps 函数

typescript

const props = defineProps({...});
  • Vue 3 特有语法:用于声明组件接收的 props

  • 返回响应式对象:包含所有已声明的 props

3. applyBasicInfo 属性

typescript

{type: Object as () => ApplyBasicInfo,required: true
}
  • 运行时类型Object 表示接受对象类型(Vue 的运行时校验)

  • 类型断言as () => ApplyBasicInfo 为 TypeScript 提供类型提示

  • 实际效果

    typescript

    // 使用时可以获得类型提示
    props.applyBasicInfo.id // 提示 number 类型
    props.applyBasicInfo.name // 提示 string 类型
4. operateCommandType 属性

typescript

{type: String,default: "info-view"
}
  • 标准 Vue 校验:接受字符串类型

  • 默认值:当父组件未传递时默认为 "info-view"


🌟 代码特点

特性说明
双重校验Vue 运行时类型检查 + TypeScript 静态类型提示
明确契约通过 ApplyBasicInfo 接口明确定义数据结构
渐进式类型不需要完全迁移到 TypeScript 也能获得部分类型优势
代码可维护性接口修改只需改动一处定义

🆚 不同写法的对比

这种写法纯 TypeScript 写法纯 JavaScript 写法
类型提示✅ 完整类型提示✅ 完整类型提示❌ 无
运行时校验✅ Vue 会校验 Object 类型❌ 需额外配置✅ 标准校验
默认值支持✅ 直接通过 default 设置❌ 需要使用 withDefaults✅ 原生支持
代码复杂度🟡 中等🟢 简洁(类型优先)🔴 高(需自行维护类型约束)

💡 为什么这样写?

  1. 平衡开发体验

    • 获得 TypeScript 的智能提示

    • 保留 Vue 的运行时校验安全网

  2. 渐进增强

    • 适合逐步将 JavaScript 项目迁移到 TypeScript

    • 不需要一次性重写所有类型

  3. 明确数据契约

    typescript

    // 父组件使用时
    <MyComponent :apply-basic-info="{id: 123,           // ✅ 必须 numbername: '张三',       // ✅ 必须 stringstatus: 'pending',  // ✅ 必须是枚举值createTime: new Date() // ✅ 必须 Date}"
    />

⚠️ 常见错误示例

typescript

// 错误1:缺少必填字段
props.applyBasicInfo.missingProp // ❌ TS 报错:属性不存在// 错误2:类型不匹配
props.applyBasicInfo.id = "100" // ❌ TS 报错:不能将 string 赋给 number// 错误3:错误的值类型
<MyComponent :apply-basic-info="'字符串'" /> 
// ❌ Vue 控制台警告:期望 Object,得到 String

🛠️ 在组件中的使用

vue

<script setup>
// 获得智能提示
const submit = () => {console.log(props.applyBasicInfo.id) // 正确:number 类型console.log(props.operateCommandType.toUpperCase()) // 正确:string 方法
}// 类型安全操作
const statusLabel = computed(() => {switch(props.applyBasicInfo.status) {case 'pending': return '审批中';case 'approved': return '已通过';// case 'rejected' 会触发 TS 错误(如果接口中未定义)}
})
</script>

📌 最佳实践建议

  1. 保持接口同步:当 ApplyBasicInfo 类型修改时,需要同步更新所有使用它的组件

  2. 默认值处理:对于复杂对象 prop,建议:

    typescript

    // 使用解构默认值
    const { applyBasicInfo = DEFAULT_INFO } = toRefs(props)
  3. 文档注释:在接口定义处添加详细注释

    typescript

    interface ApplyBasicInfo {/** 申请ID,唯一标识 */id: number;/** 申请人姓名 */name: string;// ...
    }

这种写法特别适合需要逐步引入 TypeScript 的 Vue 项目,既能享受类型系统的优势,又不会完全颠覆原有的开发模式。

3.3、与3.1等效的TypeScript 的类型声明写法

import { toRefs } from "vue";
import type { ApplyBasicInfo } from "@/interface";const props = defineProps<{applyBasicInfo: ApplyBasicInfo;operateCommandType: string;
}>();// 需要单独定义默认值
const { operateCommandType = "info-view" } = toRefs(props);

这段代码是 Vue 3 组合式 API 中使用 TypeScript 的类型声明写法,主要用于定义组件的 props。让我们分步详细解释:

  1. defineProps 的作用

    • 这是 Vue 3 的组合式 API 函数,用于声明组件接收的 props

    • 类似于选项式 API 中的 props 选项,但更符合组合式 API 的编程风格

  2. 泛型参数 <...>

    • 这是 TypeScript 的泛型语法,用于为 defineProps 提供类型注解

    • 泛型参数中定义了一个对象类型,描述了这个组件接收的所有 props 及其类型

  3. props 具体定义

    typescript

    {applyBasicInfo: ApplyBasicInfo;operateCommandType: string;
    }
    • 声明了组件需要接收两个 props:

    a) applyBasicInfo

    • 类型为 ApplyBasicInfo(这应该是一个自定义的 TypeScript 类型/接口)

    • 可能是一个包含申请基本信息的对象,比如:

      typescript

      interface ApplyBasicInfo {id: number;applicantName: string;applyDate: Date;// ...其他字段
      }

    b) operateCommandType

    • 类型为 string

    • 可能用于表示操作命令类型,比如:"create"、"edit"、"view" 等字符串枚举值

  4. 最终结果

    • 定义了一个名为 props 的常量

    • 该常量包含两个响应式属性:

    javascript

    {applyBasicInfo: { /* 具体数据 */ },operateCommandType: "edit" // 示例值
    }
  5. 在组件中的使用

    vue

    // 父组件使用
    <ChildComponent :applyBasicInfo="myApplyInfo" operateCommandType="edit"
    />// 子组件内使用
    console.log(props.applyBasicInfo.applicantName)
    console.log(props.operateCommandType)
  6. 类型检查

    • 如果父组件传递错误类型的 prop,TypeScript 会给出编译时错误

    • 例如:传递数字类型的 operateCommandType 会报错

  7. 对比 JavaScript 版本
    如果是纯 JavaScript,等效写法可能是:

    javascript

    const props = defineProps({applyBasicInfo: {type: Object,required: true},operateCommandType: {type: String,default: 'view'}
    })

注意事项

  1. 需要确保 ApplyBasicInfo 类型已经在项目中定义(通常是在独立的类型声明文件中)

  2. 这种写法需要 Vue 3.3+ 版本支持

  3. 如果不需要 TypeScript 类型检查,可以使用运行时声明方式

  4. 这种写法默认 props 都是 required 的,如果需要可选参数,应该使用 propName?: Type 的语法

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词