哈喽,各位小伙伴,欢迎来到我是wangfang呀的博客!我是我是wangfang呀,虽然还在编程的“菜鸟”阶段,但我已经迫不及待地想和大家分享我一路上踩过的坑和学到的小技巧。如果你也曾为bug头疼,那么你来对地方了!今天的内容希望能够给大家带来一些灵感和帮助。
前言
做过几个应用,再写几个通用组件就想 “一炮打响”?醒醒,真正好用的组件库背后,隐藏着对目录组织、打包策略、文档体验、主题化能力的深刻考量。今天我们就手把手,从零到一落地一个企业级 Vue 组件库的实战技巧!
一、目录结构设计 —— 分层管理,模块化最佳实践
一个清晰的目录让团队协作、高效维护一目了然。推荐结构:
my-vue-lib/
├── package.json
├── vite.config.ts # 构建工具配置
├── tsconfig.json
├── src/
│ ├── components/ # 可复用组件
│ │ ├── Button/ # 单个组件
│ │ │ ├── index.vue
│ │ │ ├── props.ts
│ │ │ ├── style.scss
│ │ │ └── README.md # 组件文档
│ │ └── Modal/
│ ├── styles/ # 全局样式、变量、Mixin
│ │ ├── variables.scss
│ │ └── mixins.scss
│ ├── utils/ # 工具函数、类型声明
│ └── index.ts # 统一导出组件
├── docs/ # 文档源码 (Storybook 或 VitePress)
├── dist/ # 构建产物
└── .storybook/ # Storybook 配置
- components/:每个组件独立文件夹,便于拆分包、按需引入。
- styles/:集中管理 SASS/LESS 变量、全局 mixin。
- utils/:通用函数、类型、hooks。
- docs/ & .storybook/:文档展示与开发预览。
二、组件打包与按需加载 —— “瘦身”与“即需即取”
2.1 Rollup/Vite 打包配置
// vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import dts from 'vite-plugin-dts'
export default defineConfig({
plugins: [
vue(),
dts() // 生成类型声明
],
build: {
lib: {
entry: 'src/index.ts',
name: 'MyVueLib',
formats: ['es', 'cjs', 'umd'],
fileName: (format) => `my-vue-lib.${format}.js`
},
rollupOptions: {
external: ['vue'], // 外部化 Vue,避免打包进库
output: {
globals: { vue: 'Vue' }
}
}
}
})
2.2 按需加载
- ES Module:用户可
import { Button, Modal } from 'my-vue-lib'
- babel-plugin-import 或 unplugin-vue-components:自动按需引入组件和样式
// babel.config.js
plugins: [
['import', {
libraryName: 'my-vue-lib',
customName: (name) => `my-vue-lib/es/${name}`,
style: (name) => `my-vue-lib/es/${name}/style.css`
}]
]
三、文档自动生成 —— Storybook & VitePress 深度结合
3.1 Storybook 快速上手
npx sb init --builder vite
在 .storybook/main.js
中:
module.exports = {
stories: ['../src/components/**/*.stories.@(js|tsx|mdx)'],
addons: ['@storybook/addon-essentials'],
framework: '@storybook/vue3'
}
每个组件旁建一个 .stories.ts
:
import Button from './index.vue'
export default { title: 'Button', component: Button }
export const Primary = () => ({
components: { Button },
template: '<Button type="primary">主要按钮</Button>'
})
3.2 VitePress 文档站
npm init vitepress
在 docs/.vitepress/config.js
配置侧边栏:
module.exports = {
title: 'MyVueLib',
themeConfig: {
sidebar: [
{ text: '快速开始', link: '/guide/' },
{ text: '组件', items: [
{ text: 'Button 按钮', link: '/components/button' },
{ text: 'Modal 对话框', link: '/components/modal' }
]}
]
}
}
用 MDX 风格插入 live-demo:
# Button
::: demo src="../../src/components/Button/index.vue" style="height: 200px;"
:::
四、主题切换与自定义样式支持 —— 多套皮肤随心换
4.1 CSS 变量 & SASS 变量方案
在 styles/variables.scss
定义:
:root {
--color-primary: #409eff;
--font-size-base: 14px;
}
组件中用:
.button {
background-color: var(--color-primary);
font-size: var(--font-size-base);
}
切换主题只需改 :root 变量:
function switchTheme(theme) {
const vars = {
light: { '--color-primary': '#409eff' },
dark: { '--color-primary': '#2b2b2b' }
}
Object.entries(vars[theme]).forEach(([k, v]) => {
document.documentElement.style.setProperty(k, v)
})
}
4.2 动态加载主题样式
- 在组件库中打包多个主题 CSS:
my-vue-lib.theme-light.css
/.theme-dark.css
- 在应用侧根据用户偏好动态
import()
:
import(`my-vue-lib/theme-${theme}.css`)
结语
一个成熟的组件库,不只是把零散组件搬到 npm 上,更是一整套目录规范、构建策略、文档体验和主题化能力的完整工程。 掌握上面四大关键:结构化目录 → 智能打包 → 文档自动 → 主题定制,你的组件库才能真正“好用又好看”,获得团队和社区的认可!
准备好打造下一个热门开源组件库了吗?动手就是最好的学习!
好啦,今天的内容就先到这里!如果觉得我的分享对你有帮助,给我点个赞,顺便评论吐个槽,当然不要忘了三连哦!感谢大家的支持,记得常回来,我是wangfang呀等着你们的下一次访问!