搭建vue3 & ts组件库脚手架
目标
pnpm
搭建monorepo
项目,和使用workspace
测试组件库- 组件支持
typescript
,可以被使用的项目识别 - 组件支持整体导入、按需自动导入
环境要求
node ≥ 18
, pnpm ≥ 8
, vue ≥ 3.3
初始化项目模板
首先使用vite
和pnpm
创建一个项目模板,这里使用pnpm
,方便后面monorepo
的使用。
pnpm create vite
在交互命令中填写项目名称,选择 Vue + Typescript 模板
然后进入项目目录,使用 pnpm install
安装依赖
使用monorepo管理组件库
使用 monorepo
可以将多个包放在一下项目下维护,包之间可以互相引用,相同的依赖和配置也可以统一维护起来。除了组件库,可能后面还会新增工具库和插件库,使用monorepo
可以更好的进行管理。
创建过程如下:
-
首先指定
monorepo
目录。在项目根目录创建packages
文件夹和pnpm-workspace.yaml
文件,文件的内容为:packages: - 'packages/**'
这样就可以指定项目
packages
下的文件夹为子包。 -
在
packages
文件夹下新建components
文件夹,并在新建的文件夹中新建一个package.json
文件,初始内容如下:{ "name": "@giegie/components", "version": "0.0.1", "description": "练习了2年半的高性能组件库", "scripts": {} }
其中
@giegie/component
是npm
包的名称,@giegie
是包的作用域,可以避免包的冲突。
创建第一个组件
先来创建一个简单的 Input
组件用作测试,如图所示,需要在src
下建立一个Input
文件夹,且需要创建几个固定的文件:
-
style/index.scss
— 用于定义组件的样式。在里面补充一点简单的样式:.gie-input { &__control { color: red; } }
为什么样式要拆开而不是直接写在Input组件里呢? 因为需要在构建时打包成一个css文件用于组件库整体导入。按需导入时,样式放在约定的目录,也方便让按需导入的插件自动引入样式。
-
Input.ts
— 用于定义类型文件,如Input
的props
类型,emit
类型和instance
类型等,内容如下:import Input from './Input.vue'; /** * 定义props类型 */ export interface InputProps { modelValue: string; disabled?: boolean; } /** * 定义emit类型 */ export type InputEmits = { 'update:modelValue': [value: string]; }; /** * 定义instance类型 */ export type InputInstance = InstanceType<typeof Input>;
InputInstance
是用来干啥的? 在写公共组件时,会使用defineExpose暴露一些方法。如在element-plus
中,就会使用formRef.validate
来校验表单,instance
里就有暴露方法的类型签名。 -
Input.vue
— 组件文件。内容如下:<template> <div class="gie-input"> <input v-model="state" ref="inputRef" class="gie-input__control" type="text" :disabled="props.disabled" /> </div> </template> <script setup lang="ts"> import { computed, ref } from 'vue'; import type { InputEmits, InputProps } from './Input'; defineOptions({ name: 'GieInput', }); const emit = defineEmits<InputEmits>(); const props = withDefaults(defineProps<InputProps>(), { modelValue: '', disabled: false, }); const state = computed({ get: () => props.modelValue, set: (val) => { emit('update:modelValue', val); }, }); const inputRef = ref<HTMLInputElement>(); function focus() { inputRef.value?.focus(); } defineExpose({ focus, }); </script>
在该组件中简单的定义了组件名、代理了一下
v-model
,并暴露出了一个方法focus
。 -
index.ts
— 定义Input
组件的入口文件import { withInstall } from '../utils/install'; import Input from './Input.vue'; export const GieInput = withInstall(Input); export default GieInput; export * from './Input.vue'; export * from './Input';
在入口文件中,使用
withInstall
封装了一下导入的Input
组件,并默认导出。且在下面导出了所有类型文件。这个
标签:vue,自己,element,开发,plus,components,组件,import From: https://www.cnblogs.com/wp-leonard/p/17894496.htmlwithInstall
函数的作用就是把组件封装成了一个可被安装,带install
方法的vue
插件,这个函数是直接从element-plus
项目复制的