element-plus源码解读4——withInstall全局方法

48 阅读3分钟

withInstall位于packages/utils/vue/install.ts

withInstall是一个工具函数,用于将 Vue 组件转换为 Vue 插件,使其支持 Vue 的插件 API。

vue关于Plugins插件的篇章:插件 | Vue.js

Object.values(): Object.values() - JavaScript | MDN

Object.entries(): Object.entries() - JavaScript | MDN

/**
 * withInstall 函数用于将组件或指令安装到 Vue 应用中。
 * 它接受两个参数:
 * - main: 主组件或指令
 * - extra: 可选的额外组件或指令
 *
 * 返回值是一个组件或指令,它具有 install 方法,可以将主组件或指令安装到 Vue 应用中。
 *
 * 示例:
 * const Button = withInstall(ButtonComponent, { ButtonGroup })
 * Button.install(app)
 *
 * 在这个例子中,Button 组件被安装到 Vue 应用中,并且 ButtonGroup 组件也被安装到 Vue 应用中。
 *
 */
 
 
export const withInstall = <T, E extends Record<string, any>>(
  main: T,
  extra?: E
) => {
  // ;防止前一行代码缺少分号导致语法错误
  // (main as SFCWithInstall<T>)将main断言为SFCWithInstall<T>类型
  // main.install = (app): void => {} 给main添加install方法
  ;(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
}

element-plus 项目中所有使用 withInstall 的组件列表:

使用 withInstall 的组件列表

1. 简单用法(只传入主组件)

这些组件只使用主组件,没有额外组件:

  • affix - 固钉
  • alert - 警告
  • anchor - 锚点
  • autocomplete - 自动完成
  • avatar - 头像
  • backtop - 回到顶部
  • badge - 徽章
  • calendar - 日历
  • card - 卡片
  • carousel - 走马灯
  • cascader-panel - 级联选择器面板
  • check-tag - 可选择标签
  • checkbox - 复选框
  • collapse-transition - 折叠过渡
  • col - 列
  • color-picker-panel - 颜色选择器面板
  • config-provider - 全局配置
  • countdown - 倒计时
  • date-picker-panel - 日期选择器面板
  • descriptions - 描述列表
  • dialog - 对话框
  • divider - 分割线
  • drawer - 抽屉
  • dropdown - 下拉菜单
  • empty - 空状态
  • form - 表单
  • icon - 图标
  • image - 图片
  • image-viewer - 图片查看器
  • input - 输入框
  • input-number - 数字输入框
  • input-tag - 输入标签
  • link - 链接
  • mention - 提及
  • message - 消息提示
  • notification - 通知
  • page-header - 页头
  • pagination - 分页
  • popconfirm - 气泡确认框
  • popover - 弹出框
  • popper - 弹出层
  • progress - 进度条
  • radio - 单选框
  • rate - 评分
  • result - 结果
  • row - 行
  • scrollbar - 滚动条
  • segmented - 分段控制器
  • select-v2 - 选择器 V2
  • skeleton - 骨架屏
  • slider - 滑块
  • space - 间距
  • splitter - 分割面板
  • statistic - 统计数值
  • steps - 步骤条
  • switch - 开关
  • table-v2 - 表格 V2
  • tag - 标签
  • teleport - 传送门
  • text - 文本
  • time-picker - 时间选择器
  • time-select - 时间选择
  • timeline - 时间线
  • tooltip - 文字提示
  • transfer - 穿梭框
  • tree - 树形控件
  • tree-select - 树形选择
  • tree-v2 - 树形控件 V2
  • upload - 上传
  • watermark - 水印

示例:

export const ElInput: SFCWithInstall<typeof Input> = withInstall(Input)

2. 带额外组件(传入 extra 参数)

这些组件包含子组件,通过 extra 参数一起注册:

Button(按钮)

export const ElButton: SFCWithInstall<typeof Button> & {
  ButtonGroup: typeof ButtonGroup
} = withInstall(Button, {
  ButtonGroup,
})

Container(布局容器)

export const ElContainer: SFCWithInstall<typeof Container> & {
  Aside: typeof Aside
  Footer: typeof Footer
  Header: typeof Header
  Main: typeof Main
} = withInstall(Container, {
  Aside,
  Footer,
  Header,
  Main,
})

Tabs(标签页)

export const ElTabs: SFCWithInstall<typeof Tabs> & {
  TabPane: typeof TabPane
} = withInstall(Tabs, {
  TabPane,
})

Menu(菜单)

export const ElMenu: SFCWithInstall<typeof Menu> & {
  MenuItem: typeof MenuItem
  MenuItemGroup: typeof MenuItemGroup
  SubMenu: typeof SubMenu
} = withInstall(Menu, {
  MenuItem,
  MenuItemGroup,
  SubMenu,
})

Breadcrumb(面包屑)

export const ElBreadcrumb: SFCWithInstall<typeof Breadcrumb> & {
  BreadcrumbItem: typeof BreadcrumbItem
} = withInstall(Breadcrumb, {
  BreadcrumbItem,
})

其他带额外组件的:

  • table - 表格(包含子组件)
  • tour - 漫游式引导(包含子组件)
  • date-picker - 日期选择器(可能包含子组件)
  • color-picker - 颜色选择器(可能包含子组件)
  • select - 选择器(可能包含子组件)
  • cascader - 级联选择器(可能包含子组件)

统计

  • 总计:约 86 个文件使用 withInstall
  • 简单用法:约 70+ 个组件
  • 带额外组件:约 10+ 个组件

所有 Element Plus 组件都通过 withInstall 包装,以支持 Vue 插件 API,便于全局注册和按需使用。