组件库设计与开发:打造可复用的组件生态
组件库设计与开发打造可复用的组件生态大家好我是蔓蔓。在大厂工作时我主导开发过团队内部的组件库大大提升了开发效率。今天我来和大家分享组件库设计与开发的完整方案。组件库架构设计目录结构my-ui-library/ ├── packages/ │ ├── button/ │ │ ├── src/ │ │ │ └── Button.vue │ │ ├── index.js │ │ └── package.json │ ├── input/ │ └── ... ├── docs/ │ └── components/ ├── scripts/ │ └── build.js ├── jest.config.js └── package.json核心原则// 1. 单一职责原则// 一个组件只做一件事// 2. 可组合性// 组件可以互相组合使用// 3. 可配置性// 通过props配置减少magic// 4. 良好的默认值// 开箱即用减少配置// 5. 完整的文档和示例// 降低使用门槛基础组件开发按钮组件template button :classbuttonClasses :disableddisabled || loading clickhandleClick span v-ifloading classloadingloading.../span span v-else slot/slot /span /button /template script export default { name: Button, props: { type: { type: String, default: default, validator: value [default, primary, success, warning, danger].includes(value) }, size: { type: String, default: medium, validator: value [small, medium, large].includes(value) }, disabled: { type: Boolean, default: false }, loading: { type: Boolean, default: false } }, computed: { buttonClasses() { return [ my-button, my-button--${this.type}, my-button--${this.size}, { is-disabled: this.disabled, is-loading: this.loading } ] } }, methods: { handleClick(event) { if (!this.disabled !this.loading) { this.$emit(click, event); } } } } /script style scoped .my-button { display: inline-flex; align-items: center; justify-content: center; border: 1px solid #ddd; border-radius: 4px; padding: 8px 16px; font-size: 14px; cursor: pointer; transition: all 0.3s; } .my-button--primary { background-color: #1890ff; color: white; border-color: #1890ff; } .my-button--success { background-color: #52c41a; color: white; border-color: #52c41a; } .my-button--small { padding: 4px 12px; font-size: 12px; } .my-button--large { padding: 12px 20px; font-size: 16px; } .is-disabled { opacity: 0.6; cursor: not-allowed; } /style表单组件template div classmy-input-wrapper label v-iflabel :classlabelClass {{ label }} span v-ifrequired classrequired*/span /label input refinputRef v-modelinnerValue :classinputClasses :placeholderplaceholder :disableddisabled :typetype focushandleFocus blurhandleBlur inputhandleInput / div v-iferrorMessage classerror-message{{ errorMessage }}/div /div /template script export default { name: Input, inheritAttrs: false, props: { modelValue: [String, Number], label: String, type: { type: String, default: text }, placeholder: String, disabled: Boolean, required: Boolean, rules: { type: Array, default: () [] }, clearable: Boolean }, data() { return { innerValue: this.modelValue, isFocused: false, errorMessage: } }, watch: { modelValue(val) { this.innerValue val; } }, computed: { inputClasses() { return [ my-input, { is-focused: this.isFocused, is-error: this.errorMessage } ] }, labelClass() { return [my-input__label, { is-required: this.required }] } }, methods: { handleFocus() { this.isFocused true; this.$emit(focus); }, handleBlur() { this.isFocused false; this.$emit(blur); this.validate(); }, handleInput(event) { this.$emit(update:modelValue, event.target.value); this.$emit(input, event); }, validate() { for (const rule of this.rules) { if (rule.required !this.innerValue) { this.errorMessage rule.message || 此字段必填; return false; } if (rule.pattern !rule.pattern.test(this.innerValue)) { this.errorMessage rule.message || 格式不正确; return false; } } this.errorMessage ; return true; }, clear() { this.innerValue ; this.$emit(update:modelValue, ); } } } /script组件库构建使用Vite构建// vite.config.jsimport{defineConfig}fromvite;importvuefromvitejs/plugin-vue;import{resolve}frompath;exportdefaultdefineConfig({plugins:[vue()],build:{lib:{entry:resolve(__dirname,packages/index.js),name:MyUI,formats:[es,umd]},rollupOptions:{external:[vue],output:{globals:{vue:Vue}}}}});package.json{name:my-ui-library,version:1.0.0,description:A Vue 3 component library,main:dist/my-ui-library.umd.js,module:dist/my-ui-library.es.js,types:dist/index.d.ts,files:[dist],scripts:{build:vite build,test:jest,lint:eslint packages/},peerDependencies:{vue:^3.0.0},devDependencies:{vitejs/plugin-vue:^4.0.0,vite:^4.0.0,jest:^29.0.0}}组件库文档使用VitePress# Button 按钮 ## 基础用法 Button typeprimary主要按钮/Button Button typesuccess成功按钮/Button vue Button typeprimary主要按钮/ButtonAPIProps参数说明类型默认值type类型string‘default’size尺寸string‘medium’Events事件名说明回调参数click点击event## 总结 一个好的组件库能显著提升团队开发效率。通过合理的架构设计注重组件的可复用性和可维护性提供完善的文档和示例你的组件库会成为团队的宝贵资产。 技术应当有温度好的组件库能让开发者更专注于业务逻辑。