携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情
上回聊了下 buildProps 函数的“带约束的泛型 Props”,本文继续分析其返回值,以及函数内容
buildProps 返回值
通过花括号 {},判断返回值应该是一个 object
{
[K in keyof Props]: IfEpProp<
Props[K],
Props[K],
IfNativePropType<Props[K], Props[K], EpPropConvert<Props[K]>>
>
}
其 key 是 [K in keyof Props],value 通过 IfEpProp 的返回
[K in keyof Props]
举个简单例子
person 是一个有 name, age 等属性的类型,通过 keyof,取出、并将所有属性转成了联合类型。再通过 [K in 联合类型],遍历所有属性类型,得到新的类型 personType,他们的值是 person[K]
值判断
源码中通过 IfEpProp, IfNativePropType, EpPropConvert 三部分,对 Props[K] 做了判断、转换。
- IfEpProp: 如果是 EpProp 类型,则直接输出
- IfNativePropType: 如果是原生Prop类型,则直接输出
- EpPropConvert: 否则,转换成 EpPropFinalized 输出
buildProps 函数实际内容
函数体实际就是箭头函数后面的部分
fromPairs(
Object.entries(props).map(([key, option]) => [
key,
buildProp(option as any, key),
])
) as any
大致流程如下
- Object.entries 将 props 转换为二维数组
- 将二维数组以 key option 的形式取出,实际上就是拿到了 props 中的参数的 key 和 value
- 将 value 通过 buildProp 函数处理一下
- fromPairs 又将二维数组转换成 object
通过源码中注释可以知道,buildProp 是为了 “生成 prop,能更好地优化类型”。 所以最终结论,就是对 props 中的所有 value 进行类型优化
这么说有点生硬了,举个例子: 我们的 Props 如下:
{
name: {
type: String,
default: 'sun',
},
age: {
type: Number,
default: 18,
},
}
经过 Object.entries 后,转换为
[
['name', {type:String, default:'sun'}],
['age', {type:Number, default:18}],
]
通过 map 遍历,key 是 'name', option 是 {type:String, defalut: 'sun'} ,再通过 buildProp 函数将其转化为 EpPropFinalized 类型
{
0: false,
1: true,
default: "sun",
required: false,
type: String,
validator: undefined,
__epPropKey: true
}
遍历结束后,通过 fromPairs 转回 object,最终返回结果。
小结
Element Plus 的 buildProps 方法,说白了就是对 element 组件开发过程中,大家编码时的 Props 的设置,进行了统一格式化,或者说优化类型。
补充:阅读组件的方式
关于如何阅读源码,我觉得如果能对源码进行调试,就能更快的理解到每个步骤,原作者想要达到什么目的,也能印证自己阅读源码时的猜测。
对于UI类型的组件源码阅读,以 Card.vue 为例:
- 新建一个工程,通过 npm install 引入库 Element Plus
- 将源码下载下来,并拷贝源码中的 Card.vue 到新工程中
- 修改拷贝过来的源码的 import 引用(源码一般是相对路径的引用,这里修改为从我们工程中 install 下来的路径)
- import 修改完,基本上就万事大吉了。 这时就可以在工程中引用 拷贝过来的源码了