组件库开发
搭建项目
使用 vite
创建一个 vue 项目
pnpm create vite
安装依赖
pnpm i
安装 element-plus
pnpm install element-plus
改造项目
删除 assets 目录,删除 components 目录,新建 packages 目录,清空App.vue里的代码
![](https://file.jishuzhan.net/article/1782347682262552577/e2c736d664065399a7bf73f7069ee00c.webp)
组件封装
- 创建组件文件
在src\packages
目录下新建 button 组件
![](https://file.jishuzhan.net/article/1782347682262552577/051e670e616e61b9dfa9abab6603c313.webp)
- 导出组件
在src\packages
目录下新建index.js
用于导出组件
![](https://file.jishuzhan.net/article/1782347682262552577/7a8680c4e5940f41a47b0819457d52d9.webp)
- 本地验证组件是否可用
在main.js
中注册组件
![](https://file.jishuzhan.net/article/1782347682262552577/9a41e64e70cd6fc6e9eacda9a6c8d89c.webp)
在App.vue
中使用按钮
![](https://file.jishuzhan.net/article/1782347682262552577/db4e6c64ff8f3b99065d2256a7de4583.webp)
在终端运行pnpm dev
启动项目
组件库打包
配置 vite.config.js 文件,运行打包命令 pnpm build
进行打包
php
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from "path";
export default defineConfig({
build: {
outDir: "lib", //输出目录名称
lib: {
entry: resolve(__dirname, "./src/packages/index.js"),
name: "xzl-ui",
fileName: 'xzl-ui',
},
rollupOptions: {
external: ['vue'],
output: {
// 在 UMD 构建模式下为这些外部化的依赖提供一个全局变量,为了确保在构建后的库文件中能够正确地访问到 Vue 库的 API
globals: {
vue: 'Vue'
}
}
}
},
plugins: [vue()],
})
上传组件库到npm官网
在打包好的 lib 目录下,执行pnpm init
命令初始化 package.json
![](https://file.jishuzhan.net/article/1782347682262552577/741908645217a9d4412e148eaf4b7b57.webp)
注册 npm 账号,执行 npm login
登录到 npm。执行npm publish
就可以正式发布到 npm 仓库。
![](https://file.jishuzhan.net/article/1782347682262552577/31bb24606d26d00d40b42c8dd9d092b5.webp)
上传成功后可以在 npm官网 上查到自己上传的组件
扩展
组件封装需要考虑哪些因素?
- 单一责任原则: 每个组件应该专注于一个特定的功能或用途。有助于组件的可维护性,使其更容易理解和调试。
- 组件的可复用性: 将通用的功能封装成可复用的组件,这样在不同的地方都可以使用相同的逻辑和界面。尽量使组件的耦合度低,使其能够在不同的上下文中使用。
- 抽象和接口设计: 定义清晰的组件接口,包括props、事件和插槽(slot)等,以便组件的用户能够以一种直观的方式使用它。
- 可定制性: 为组件提供足够的选项和配置,使用户可以根据自己的需求对组件进行定制。这可以通过props、样式类、插槽等方式实现。
- 状态管理: 决定是否需要将状态内置到组件中,或者将状态管理留给组件的使用者。
- 样式和样式隔离: 考虑组件的样式,尽量使用局部作用域的样式,以避免样式污染和冲突。可以使用CSS Modules、Scoped CSS或CSS-in-JS等方式实现样式隔离。
- 文档和示例: 提供清晰的文档和示例,帮助其他开发者了解如何正确使用你的组件。文档应该包括组件的属性、方法、事件以及示例代码。
二次封装组件的技巧及要点
- 保持原有组件的接口
对 Element-plus 的 input 组件进行简单的二次封装,封装一个 MyInput 组件,代码的结构如下:
javascript// 引入组件进行使用 <template> <MyInput></MyInput> </template> // MyInput.vue <template> <div class="my-input"> <el-input></el-input> </div> </template>
继承第三方组件的 Attributes 属性和 Event 事件
xml<template> <div class="my-input"> <el-input v-bind="$attrs"></el-input> </div> </template>
使用第三方组件的 Slots
xml<template> <div class="my-input"> <el-input v-bind="attrs"> <template v-for="(value, name) in slots" #[name]="scope"> <slot :name="name" v-bind="scope || {}"></slot> </template> </el-input> </div> </template> <script setup> import { useSlots } from "vue"; const slots = useSlots(); </script>
使用第三方组件的Methods
xml<template> <div class="my-table"> <el-table ref="table"></el-table> </div> </template> <script lang="ts" setup> import { ref, onMounted, defineExpose } from 'vue' import { ElTable } from 'element-plus' const table = ref(); const expose = {}; onMounted(() => { const entries = Object.entries(table.value); for (const [method, fn] of entries) { expose[method] = fn; } }); defineExpose(expose); </script> <template> <MyTable ref="tableRef"></MyInput> </template> <script lang="ts" setup> import { ref,onMounted } from 'vue' const tableRef = ref() onMounted(() => { console.log(tableRef.value); // 调用子组件中table的方法 tableRef.value.clearSort() }) </script>
组件库文档搭建
Storybook
文档:storybook.js.org/docs/get-st...
Storybook 是一个开源的前端 UI 组件开发和测试工具,它可以让你独立于应用程序来开发和测试 UI 组件。
安装 Storybook
执行命令 pnpm dlx storybook@latest init
![](https://file.jishuzhan.net/article/1782347682262552577/8306f51db2b19c0fc1cac12826e7c6fe.webp)
安装成功后会在项目中生成如下文件
![](https://file.jishuzhan.net/article/1782347682262552577/24f9f1dc11faf7afd632159cec5dee98.webp)
运行 pnpm storybook
即可直接预览文档
编写 stories
stories 应该放在哪?
组件的 stories 在与组件文件一起存在的 stories 文件中定义。该 stories 文件仅供开发使用,不会包含在生产包中。
story 文件以 .stories.js 结尾,每个 story 文件为一个菜单项,default 导出为页面配置 (组件、标题等)
export 导出为组件的每种 Props 枚举的样式,可添加多种展示方式。
![](https://file.jishuzhan.net/article/1782347682262552577/d65745da049b71388f24e0fccbc6a940.webp)
VitePress
VitePress 是什么
VitePress 是一个静态站点生成器,VitePress 获取用 Markdown 编写的内容,对其应用主题,并生成可以轻松部署到任何地方的静态 HTML 页面。
使用场景
文档、博客、档案和营销网站
安装 vitepress
执行命令 pnpm add -D vitepress
初始化项目
使用 pnpm vitepress init
命令构建一个基本项目
启动项目
使用 pnpm run docs:dev
命令启动具有即时热更新的本地开发服务器
编写文档
VitePress 使用 Markdown 生成内容,内置 Markdown 扩展:表格、语法高亮等,同时 Markdown 进行 Vue 增强,每个 Markdown 页面都是 Vue 单文件组件。
在 Markdown 使用 Vue:Markdown 文件中的根级
ini
# Button 按钮
常用的操作按钮
## 基础用法
使用 `type`, `plain`, `round` 和 `circle` 来定义按钮的样式
<script setup>
import XZLButton from '../src/packages/button/index.vue'
</script>
<XZLButton label="Default" />
<XZLButton label="Primary" type="primary" />
<XZLButton label="Success" type="success" />
<div style="margin-top: 12px">
<XZLButton label="Default" round />
<XZLButton label="Primary" type="primary" round />
<XZLButton label="Success" type="success" round />
</div>
::: details 代码
```md
<XZLButton label="Default" />
<XZLButton label="Primary" type="primary" />
<XZLButton label="Success" type="success" />
```
:::