从 Element Plus 源码,回顾 ts/js 语法(下)

1,361 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第7天,点击查看活动详情

上回聊了下 buildProps 函数的“带约束的泛型 Props”,本文继续分析其返回值,以及函数内容

image.png

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]

举个简单例子

image.png

person 是一个有 name, age 等属性的类型,通过 keyof,取出、并将所有属性转成了联合类型。再通过 [K in 联合类型],遍历所有属性类型,得到新的类型 personType,他们的值是 person[K]

值判断

源码中通过 IfEpProp, IfNativePropType, EpPropConvert 三部分,对 Props[K] 做了判断、转换。

  1. IfEpProp: 如果是 EpProp 类型,则直接输出
  2. IfNativePropType: 如果是原生Prop类型,则直接输出
  3. EpPropConvert: 否则,转换成 EpPropFinalized 输出

buildProps 函数实际内容

函数体实际就是箭头函数后面的部分

fromPairs(
    Object.entries(props).map(([key, option]) => [
      key,
      buildProp(option as any, key),
    ])
  ) as any

大致流程如下

  1. Object.entries 将 props 转换为二维数组
  2. 将二维数组以 key option 的形式取出,实际上就是拿到了 props 中的参数的 key 和 value
  3. 将 value 通过 buildProp 函数处理一下
  4. 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 为例:

  1. 新建一个工程,通过 npm install 引入库 Element Plus
  2. 将源码下载下来,并拷贝源码中的 Card.vue 到新工程中
  3. 修改拷贝过来的源码的 import 引用(源码一般是相对路径的引用,这里修改为从我们工程中 install 下来的路径)
  4. import 修改完,基本上就万事大吉了。 这时就可以在工程中引用 拷贝过来的源码了