从最简单的 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的交叉类型,为并且关系
相关推荐
小江的记录本3 小时前
【CSS】CSS 动画:transition、animation、transform、CSS3 新特性(附《思维导图》)
前端·css·安全·spring·前端框架·css3·动画
hzxpaipai4 小时前
企业官网技术架构拆解:前端、后台、数据库、服务器如何协同
前端·数据库·架构
2601_963749105 小时前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构
Eloudy6 小时前
HSB FPGA 架构总体
fpga开发·架构
yychen_java6 小时前
九:Text-to-SQL 智能数据查询与 Human-in-the-Loop 人机协作
java·人工智能·架构
wuyk5557 小时前
从零吃透Modbus通信|第7章:终极工程整合(模块化架构、双模式主机从机、RTOS适配、量产级模板)
c语言·stm32·学习·架构
人生百态,人生如梦7 小时前
每日论文解读(9.2)——SwarmBench:面向LLM Agent Swarm编排能力的多维评估基准与经验增强框架
架构·agent
Vespeng7 小时前
打破传统 MVC:在 Go 中实践高内聚的业务驱动架构
架构·go·gin
用户3434612783209 小时前
.NET 中任务调度的底层机制与你可能不知道的隐藏陷阱
架构