从最简单的 icon组件开始了解Element-Plus 源码

从基础的组件看看Element-plus实现组建的基本流程

目录 packages\components\icon

因为我们分析源码的目的是学习如何构建组件库已经封装复用性强的组件所以跳过.tsx文件从src目录开始看。

icon.ts
js 复制代码
import { buildProps, definePropType } from '@element-plus/utils'

buildProps,definePropType(export const definePropType = <T>(val: any): PropType<T> => val)。definePropType定义了泛型的props类型,buildProps是对 element 组件开发过程中,大家编码时的 Props 的设置,进行了统一格式化。

js 复制代码
import type { ExtractPropTypes } from 'vue'
import type Icon from './icon.vue'

使用 import 的话,TypeScript 是无法判断你是想导出类型还是一个 JavaScript 的方法或者变量。
所以 TypeScript 提供了 import type or export type,用来明确表示我引入/导出的是一个类型,而不是一个变量或者方法。
定义组件需要的参数
js 复制代码
export const iconProps = buildProps({

  /**
   * @description SVG icon size, size x size
   */
  size: {
    type: definePropType<number | string>([Number, String]),
  },
  /**
   * @description SVG tag's fill attribute
   */
  color: {
    type: String,
  },
} as const)

as const 则可以快速将一个对象变成只读类型,常量断言可以把一个值标记为一个不可篡改的常量,从而让 TS 以最严格的策略来进行类型推断。

js 复制代码
export type IconProps = ExtractPropTypes<typeof iconProps>

vue3 string构造函数 在TS类型中是他的构造函数类型:StringConstructor 并不是我们想要的,我们希望string构造函数返回的是字符串类型string. vue3提供了prop类型申明ExtractPropTypes 用于接收一个类型用yu把接收的prop类型返回出来;也可以把构造函数类型转换为对应的类型如:StringConstructor 转换成 string。

js 复制代码
export type IconInstance = InstanceType<typeof Icon> & unknown

返回SFC 实例类型,InstanceType 函数:该函数返回(构造) 由某个构造函数构造出来的实例类型组成的类型

icon/index.ts
js 复制代码
import { withInstall } from '@element-plus/utils'

import Icon from './src/icon.vue'

import type { SFCWithInstall } from '@element-plus/utils'
//组件类型引入
export const ElIcon: SFCWithInstall<typeof Icon> = withInstall(Icon)
// 通过 withInstall 方法给 Icon 添加了一个 install 方法
export default ElIcon
// 导出 iCON 组件

export * from './src/icon'

至此,对icon组件的分析就结束了。涉及的withInstall是组件库注册的公共方法。

具体目录是packages\utils\vue\install.ts

js 复制代码
export const withInstall = <T, E extends Record<string, any>>(
  main: T,
  extra?: E
) => {
  ;(main as SFCWithInstall<T>).install = (app): void => {
    for (const comp of [main, ...Object.values(extra ?? {})]) {
      app.component(comp.name, comp)
    }
  }

  if (extra) {
    for (const [key, comp] of Object.entries(extra)) {
      ;(main as any)[key] = comp
    }
  }
  return main as SFCWithInstall<T> & E
}
// 组件注册的公共方法
 传递两个参数,main类型为泛型T,extra是一个对象,通过Object.values 将 extra 中的属性值提取为一个数组,并进行遍历进行 组件的注册.
 
 如果extra不为空则通过 迭代器遍历 Object.entries 转换后的 二维数组, 将extra所有属性和值 挂载到 main 对象下
 
 SFCWithInstall 通过泛型 将最后返回的 main 的类型 定义为 T & Plugin & E的交叉类型,为并且关系
相关推荐
自强的小白12 分钟前
项目整个架构的构建和演进。(重点!)
spring cloud·微服务·架构
孟健19 分钟前
从单体失控到解耦管道:用 Unix 哲学重构 Anthropic 式多 Agent 动态工作流
人工智能·python·架构
这个DBA有点耶1 小时前
ELT 工具选型完整指南:从 ETL 差异分析到工程落地
数据库·架构·代码规范
147API2 小时前
AWS Priming 怎样用层级蒸馏,把 Transformer 改造成混合架构
深度学习·架构·transformer
loulanyue_2 小时前
芯片设计:从最底层讲起——读MatX CEO Reiner Pope激辩逻辑门、脉动阵列与GPU架构演进
架构
张彦峰ZYF2 小时前
一次触发、一把锁与一个号码:分布式基础组件的统一设计推演
架构·先立六条时间纪律·再拆解编号的位分配·节点编号分配与回拨四策·辨析互斥、租约与领导权三种语·调度拆成七个子问题·五层架构
码上上班2 小时前
基于 K3s 的微服务容器化与 GitOps 持续交付平台
微服务·云原生·架构
Dawson Zhu3 小时前
《Agentic Design Patterns》第 17 章导读:推理技术
人工智能·语言模型·架构·aigc·agi
各类产品分享14 小时前
制药厂 GMP 车间 AR 巡检系统落地架构与实施要点
架构·ar·ar巡检
云和恩墨4 小时前
从通用规范到系统级联动:以Skill为核心的Mopheus扩展架构与落地实践
架构