Element UI是世界级最优秀的UI框架之一。向优秀看齐,向卓越跟进,大家卷起来,通过阅读源码可以学到很有有趣的知识
技巧一:用代码来生成代码
源码入口文件生成:Element UI
目前一共有80个组件,如果要导出这80个组件,那么引入、导出和声明Vue组件的代码都要写240次,而且,组件的增删都要去修改入口文件。为了减少这部分工作量,基于components.d.ts
来对组件引入和导出。
components.d.ts
内容如下:
相较于上一个版本的components.json
来驱动新版本采用ts的方式,反而更加来的直接和干脆,分两部分来引入
- 声明组件
GlobalComponents
- 声明组件属性
ComponentCustomProperties
之后在env.d.ts
中将component.d.ts中的声明的组件及属性信息通过全局模块公开
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
导入
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.myzijiebao.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
,来对文件进行个性化配置。
<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,
export const isKorean = (text: string) =>
/([(uAC00-uD7AF)|(u3130-u318F)]) /gi.test(text)
如果是需要中文支持,则把Unicode编码进行转换即可
技巧四:引入了 hooks 来优化 mixin
由于Vue3
中仍然保留了mixin
,我们可以在特定组件或者是全局使用mixin
来复用逻辑,同时也引入了 hooks 来改善 mixin 存在的一些问题:
- 渲染上下文中公开的属性的来源不清楚。 例如,当使用多个
mixin
读取组件的模板时,可能很难确定从哪个mixin
注入了特定的属性。 - 命名空间冲突。
Mixins
可能会在属性和方法名称上发生冲突
通过引入hooks来解决这两个问题
- 暴露给模板的属性具有明确的来源,因为它们是从 Hook 函数返回的值。
- Hook 函数返回的值可以任意命名,因此不会发生名称空间冲突。
参考资料
- https://github.com/element-plus/element-plus
- https://juejin.cn/post/6914598983205847053