vue3:const props = defineProps([‘foo‘])

问:

const props = defineProps(['foo'])为什么要(['foo'])而不是('foo')他的底层源码怎么写的?

回答:

非常好的问题!我们来深入理解一下:


🧠 一、为什么是 defineProps(['foo']) 而不是 defineProps('foo')

在 Vue 3 的 <script setup> 中,defineProps 是一个编译时宏(compile-time macro),它并不是普通的 JavaScript 函数。它的写法会直接影响 Vue 编译器如何处理你的组件属性。

✅ 正确写法:

defineProps(['foo'])

或者使用对象形式:

 
 
defineProps({ foo: String })

❌ 错误写法:

defineProps('foo') // 会报错或无法正常工作

🔍 二、底层原理:Vue 是怎么处理 defineProps 的?

defineProps 并不是一个真正的运行时函数,而是 Vue 编译器在构建阶段识别并处理的语法糖。当你写:

defineProps(['foo', 'bar'])

Vue 编译器会在构建时把它转换成类似下面这样的代码:

const __props = defineProps({
  foo: null,
  bar: null
})

也就是说,['foo'] 这种数组形式,在编译时会被自动转成默认的 null 类型的 props 对象。

⚠️ 注意:你写的 defineProps(['foo']) 实际上不会真的在运行时执行,而是被 Vue 编译器提前“解析”掉了。


📌 三、那为什么不能用字符串 'foo'

因为 Vue 编译器只支持以下两种方式声明 props:

写法类型是否推荐
数组形式 ['foo', 'bar']Array<string>✅ 简单场景可用
对象形式 { foo: String }Object✅ 推荐用于类型检查和文档化

如果你传的是字符串 'foo',这既不是数组也不是对象,Vue 编译器就无法解析了,所以直接报错或忽略。


🛠 四、从源码角度看(简化版)

虽然 Vue 的源码比较复杂,但我们可以通过伪代码理解它的逻辑:

// 假设这是 Vue 编译器内部的逻辑
function processDefinePropsNode(node) {
  const args = node.arguments[0]; // 获取 defineProps 的参数

  if (args.type === 'ArrayExpression') {
    // 如果是数组 ['foo']
    createPropsFromArr(args.elements);
  } else if (args.type === 'ObjectExpression') {
    // 如果是对象 { foo: String }
    createPropsFromObj(args.properties);
  } else {
    throw new Error("Invalid prop declaration. Expected Array or Object.");
  }
}

所以,传字符串 'foo' 是不被支持的,因为它不是合法的结构。


🎯 五、总结

问题回答
为什么必须用 ['foo'] 而不是 'foo'因为 Vue 编译器只接受数组或对象形式的 props 声明
defineProps 是函数吗?不是,它是 Vue 的编译时宏,不在运行时真实存在
底层怎么处理?编译器会把 ['foo'] 转换成 { foo: null } 的对象形式
可以传字符串吗?❌ 不可以,会报错或无效
推荐哪种写法?✅ 推荐使用对象形式 { foo: String, bar: { type: Number, required: true } },更清晰且可做类型检查

如果你想了解 defineProps 在 TypeScript 下如何使用(比如配合 withDefaults),我也可以继续为你讲解 😊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值