前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >见贤思齐——从Element Plus UI 源码中学到的技巧

见贤思齐——从Element Plus UI 源码中学到的技巧

原创
作者头像
Yerik
发布2022-04-04 12:06:52
1.3K0
发布2022-04-04 12:06:52
举报
文章被收录于专栏:烹饪一朵云烹饪一朵云

Element UI是世界级最优秀的UI框架之一。向优秀看齐,向卓越跟进,大家卷起来,通过阅读源码可以学到很有有趣的知识

技巧一:用代码来生成代码

源码入口文件生成:Element UI 目前一共有80个组件,如果要导出这80个组件,那么引入、导出和声明Vue组件的代码都要写240次,而且,组件的增删都要去修改入口文件。为了减少这部分工作量,基于components.d.ts来对组件引入和导出。

components.d.ts内容如下:

components.png
components.png

相较于上一个版本的components.json来驱动新版本采用ts的方式,反而更加来的直接和干脆,分两部分来引入

  • 声明组件GlobalComponents
  • 声明组件属性ComponentCustomProperties

之后在env.d.ts中将component.d.ts中的声明的组件及属性信息通过全局模块公开

代码语言:typescript
复制
import type { vShow } from 'vue'

declare global {
  const process: {
    env: { NODE_ENV: string }
  }

  namespace JSX {
    interface IntrinsicAttributes {
      class?: any
      style?: any
    }
  }
}

declare module '@vue/runtime-core' {
  export interface GlobalComponents {
    Component: (props: { is: Component | string }) => void
  }

  export interface ComponentCustomProperties {
    vShow: typeof vShow
  }
}

export {}

经过这层铺垫之后,在element-plus/components.ts上面通过import导入

代码语言:typescript
复制
import { ElAffix } from '@element-plus/components/affix'
import { ElAlert } from '@element-plus/components/alert'
import { ElAutocomplete } from '@element-plus/components/autocomplete'
import { ElAvatar } from '@element-plus/components/avatar'
import { ElBacktop } from '@element-plus/components/backtop'
import { ElBadge } from '@element-plus/components/badge'
import {
  ElBreadcrumb,
  ElBreadcrumbItem,
} from '@element-plus/components/breadcrumb'
import { ElButton, ElButtonGroup } from '@element-plus/components/button'
/**省略 90多个组件导入**/
import { ElCarousel, ElCarouselItem } from '@element-plus/components/carousel'
import { ElCascader } from '@element-plus/components/cascader'
...

export default [
  ElAffix,
  ElAlert,
  ElAutocomplete,
  ElAvatar,
  ElBacktop,
  ElBadge,
  ElBreadcrumb,
  ElBreadcrumbItem,
  ...
] as Plugin[]

这个配置给我的启示就是在我们的项目中,可以通过这种方式对我们需要使用的组件进行再声明,限制使用范围,以减少编译后的资源占用,如下图所示

undefined.png](https://ask8088-private-1251520898.cn-south.myqcloud.com/developer-images/article/6929359/r3bwcbnpdn.png?q-sign-algorithm=sha1&q-ak=AKID2uZ1FGBdx1pNgjE3KK4YliPpzyjLZvug&q-sign-time=1649045158;1649052358&q-key-time=1649045158;1649052358&q-header-list=&q-url-param-list=&q-signature=af9e21d5d809dd12a8cbb1d94e20a944cf41c248)

技巧二:icon组件示例

Element Plus UI 提供了非常多的icon,对于这些icon,如果需要一个个写得话,又要写很多重复的物料代码,这也太累了,人工搬砖,写文档,又得加不少班呀。对于有追求的程序员,当然要有想法了。处理技巧:使用Composition API来改写组,还利用packages/hooks目录下抽取了几个可复用的 hooks,如useNamespace,以及读取icon中的iconProps,来对文件进行个性化配置。

代码语言:typescript
复制
<template>
  <i :class="ns.b()" :style="style" v-bind="$attrs">
    <slot />
  </i>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { addUnit, isUndefined } from '@element-plus/utils'
import { useNamespace } from '@element-plus/hooks'
import { iconProps } from './icon'
import type { CSSProperties } from 'vue'

defineOptions({
  name: 'ElIcon',
  inheritAttrs: false,
})
const props = defineProps(iconProps)
const ns = useNamespace('icon')

const style = computed<CSSProperties>(() => {
  if (!props.size && !props.color) return {}

  return {
    fontSize: isUndefined(props.size) ? undefined : addUnit(props.size),
    '--color': props.color,
  }
})
</script>

通过这种方式,可以极大的减少重复的工作量

技巧三:文档多语言

在项目中packages/utils/i18n.ts可以看到多语言文档的配置demo,

代码语言:typescript
复制
export const isKorean = (text: string) =>
  /([(\uAC00-\uD7AF)|(\u3130-\u318F)])+/gi.test(text)

如果是需要中文支持,则把Unicode编码进行转换即可

技巧四:引入了 hooks 来优化 mixin

由于Vue3中仍然保留了mixin,我们可以在特定组件或者是全局使用mixin来复用逻辑,同时也引入了 hooks 来改善 mixin 存在的一些问题:

  1. 渲染上下文中公开的属性的来源不清楚。 例如,当使用多个mixin读取组件的模板时,可能很难确定从哪个mixin注入了特定的属性。
  2. 命名空间冲突。 Mixins可能会在属性和方法名称上发生冲突

通过引入hooks来解决这两个问题

  1. 暴露给模板的属性具有明确的来源,因为它们是从 Hook 函数返回的值。
  2. Hook 函数返回的值可以任意命名,因此不会发生名称空间冲突。

参考资料

  1. https://github.com/element-plus/element-plus
  2. https://juejin.cn/post/6914598983205847053

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 技巧一:用代码来生成代码
  • 技巧二:icon组件示例
  • 技巧三:文档多语言
  • 技巧四:引入了 hooks 来优化 mixin
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档