@jqms/components_lib
@jqms/components_lib
JQMS 可复用 Vue 3 组件库。适用于已有 Vue 3 + Element Plus + vue-i18n 业务系统,通过插件注入宿主能力(多语言、用户信息、字典、业务 API 等),按需使用组件。
当前 npm 版本以 registry 为准(仓库内 package.json 为 1.1.0);需配合 @jqms/system_service 与 @jqms/utils 兼容版本。
目录
- 环境要求
- 安装
- 接入步骤(推荐)
- 插件配置说明
- 与 @jqms/system_service 配合
- 样式接入
- 多语言接入
- 组件清单
- 按需引入
- 宿主侧额外准备
- TypeScript
- 业务应用接入(npm)
- 仓库内开发联调
- 常见问题
- 维护者:构建与发布
环境要求
| 依赖 | 版本建议 | 说明 |
|---|---|---|
vue |
^3.5.6 |
peer |
element-plus |
^2.13.5 |
peer,需在组件库插件之前安装 |
vue-i18n |
9.2.2 |
peer |
vue-router |
^4.2.2 |
peer |
@element-plus/icons-vue |
^2.3.1 |
peer |
@vueuse/core |
^10.7.0 |
peer,Screenfull 依赖 |
echarts |
^6.0.0 |
图表组件需要 |
@wangeditor/editor / @wangeditor/editor-for-vue |
^5.1.x |
富文本组件需要 |
dayjs / lodash-es / fuse.js / file-saver / xlsx-js-style |
见 package.json | 工具类 peer |
@jqms/utils |
与现有 JQMS 体系一致 | 认证、列宽等 |
@jqms/system_service |
^1.0.0 |
用户/部门/文件/K2/客户等 HTTP Service |
组件库通过
@jqms/system_service发起业务请求,宿主只需安装并配合配置插件(i18n、用户、字典、URL 等)。
安装
# npm
npm install @jqms/components_lib
# pnpm
pnpm add @jqms/components_lib
# yarn
yarn add @jqms/components_lib
同时安装 peer 依赖(若项目尚未具备):
pnpm add vue element-plus vue-i18n vue-router @element-plus/icons-vue \
echarts dayjs lodash-es fuse.js file-saver xlsx-js-style \
@wangeditor/editor @wangeditor/editor-for-vue \
@vueuse/core @jqms/utils @jqms/system_service
接入步骤(推荐)
在宿主应用中按以下顺序完成接入。以 Vite + Vue 3 为例。
1. 引入样式
打包后组件样式在独立 CSS 中,必须手动导入,否则会出现尺寸/间距丢失等问题(例如 SvgIcon 变回默认大小)。
// main.ts
import '@jqms/components_lib/style.css'
2. 合并组件库多语言
请从 独立子入口 @jqms/components_lib/i18n 导入,不要从主入口导入 i18n helper,以避免初始化时加载完整组件包并触发 TDZ 错误。
内置语言:zh-cn、zh-tw、en。文案统一挂在 jqmsComponents.* 命名空间下,不会覆盖宿主已有的 btn、toast 等顶级 key。
// i18n/index.ts
import { createI18n } from 'vue-i18n'
import { mergeJqmsComponentsLocales } from '@jqms/components_lib/i18n'
const i18n = createI18n({
legacy: false,
globalInjection: true,
locale: 'zh-cn',
fallbackLocale: 'zh-cn',
messages: {
'zh-cn': { /* 宿主文案 */ },
'zh-tw': { /* 宿主文案 */ },
en: { /* 宿主文案 */ }
}
})
// 在 createI18n 之后、远程语言加载之前合并
mergeJqmsComponentsLocales((locale, messages) => {
i18n.global.mergeLocaleMessage(locale, messages)
})
export default i18n
3. 注册插件与图标
在 ElementPlus 和 vue-i18n 之后安装组件库插件:
// main.ts
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import '@jqms/components_lib/style.css'
import {
createJqmsComponentsPlugin,
elementIcons,
registerJqmsChartThemes
} from '@jqms/components_lib'
import vueI18n from './i18n'
import App from './App.vue'
const app = createApp(App)
// 可选:注册 ECharts 主题
registerJqmsChartThemes()
app
.use(ElementPlus)
.use(elementIcons) // 注册 Element Plus Icons,供 SvgIcon 的 ele-* 名称使用
.use(vueI18n)
.use(
createJqmsComponentsPlugin({
t: vueI18n.global.t,
getLanguage: () => 'zh-cn',
setLanguage: (language) => {
// 切换宿主语言
},
showLoading: (message) => {
// 可选:全局 loading
},
getCurrentUser: () => ({
// 返回当前登录用户对象
}),
getSideTheme: () => 'theme-dark',
getIndustrialMode: () => false,
getDictionary: () => ({
getDictsFun: (/* ... */) => {},
getComputedDict: (/* ... */) => {},
getDictLabel: (/* ... */) => {}
}),
k2ServiceUrl: import.meta.env.VITE_APP_K2_SERVICE,
uploadUrl: import.meta.env.VITE_APP_BASE_API + import.meta.env.VITE_APP_UPLOAD_URL
})
)
.mount('#app')
安装后,注册表中的组件会全局注册,可直接在模板中使用,例如 <UserPicker />、<Pagination />。
插件配置说明
createJqmsComponentsPlugin(options) 的 options 类型为 JqmsComponentsOptions:
| 字段 | 必填 | 说明 |
|---|---|---|
t |
是 | i18n 翻译函数,通常传 i18n.global.t |
getLanguage |
是 | 返回当前语言,如 'zh-cn' |
setLanguage |
否 | 切换语言;LangSelect 会调用 |
showLoading |
否 | 展示全局 loading;LangSelect 等会调用 |
getCurrentUser |
是 | 返回当前用户;上传头、客户选择等依赖 |
getSideTheme |
是 | 侧栏/图表主题,如 'theme-dark' |
getIndustrialMode |
是 | 是否工业模式;影响表格列等行为 |
getDictionary |
是 | 字典适配器,见下表 |
k2ServiceUrl |
否 | K2 流程相关 iframe 基址 |
uploadUrl |
否 | 文件上传地址 |
字典适配器 getDictionary()
需返回:
interface JqmsDictionaryAdapter {
getDictsFun: (...args: any[]) => any
getComputedDict: (...args: any[]) => any
getDictLabel: (...args: any[]) => any
}
JqmsDictSelect 通过该适配器读取字典数据。
与 @jqms/system_service 配合
组件库内部通过 @jqms/system_service 调用业务 HTTP,不再需要宿主注入 services。
| 组件能力 | system_service 子路径 |
|---|---|
| 用户选择 / 用户链接 | @jqms/system_service/user |
| 部门选择 | @jqms/system_service/dept |
| K2 流程 | @jqms/system_service/k2 |
| 上传 / 预览 / 下载 | @jqms/system_service/file |
| DCC | @jqms/system_service/dcc |
| 客户选择 | @jqms/system_service/customer |
| 字典 | @jqms/system_service/dict(通常经宿主 dictionary store 注入 getDictionary) |
业务应用也可直接 import 这些 service,与组件库共享同一实现。
样式接入
发布包导出:
@jqms/components_lib/style.css → dist/style.css
import '@jqms/components_lib/style.css'
说明:
- dist(npm 包)模式:SFC 样式已提取到该 CSS,必须手动 import。
- source(本地联调)模式:该入口指向占位 CSS,实际样式由 Vite 编译
.vue时注入;仍建议保留同一行 import,方便日后切到 npm 包。
多语言接入
为什么要用 /i18n 子入口?
// ✅ 正确:轻量入口,只含 locale + merge helper
import { mergeJqmsComponentsLocales } from '@jqms/components_lib/i18n'
// ❌ 不推荐:从主入口引入会拉起整个组件包,可能引发初始化时序问题
import { mergeJqmsComponentsLocales } from '@jqms/components_lib'
命名空间
组件内文案 key 形如:
jqmsComponents.btn.search
jqmsComponents.user.selectUser
jqmsComponents.arTask.flowHistory
...
宿主侧若要覆盖组件库文案,在自身 locale 中按同样路径覆盖即可。
合并时机
createI18n(...)mergeJqmsComponentsLocales(...)- (可选)再加载远程/服务端语言包
这样远程文案可以覆盖组件库默认文案,而组件库不会误覆盖宿主无关顶级 key。
组件清单
插件安装后全局注册以下组件(名称与 PascalCase 一致):
| 组件 | 说明 |
|---|---|
CollapseSearchCard |
可折叠搜索卡片 |
MultiSearchCard |
多条件搜索卡片 |
CustomerSelector / SelectCustomerDialog |
客户选择 |
DepartmentPicker |
部门选择 |
UserPicker / UserPickerInput |
用户选择 |
UserLink / UserInfoDialog |
用户链接与详情 |
JqmsDictSelect |
字典下拉 |
JqmsPage |
页面容器 |
PageMainLayout / PageMainBody |
主内容布局 |
Pagination |
分页 |
RightToolbar |
右侧工具栏(刷新、显隐列等) |
Screenfull |
全屏切换(支持指定 target 元素) |
Subtitle |
副标题 |
SvgIcon |
SVG / Element 图标 |
LangSelect |
语言切换 |
MailLink / PhoneLink |
邮件 / 电话链接 |
FileLink |
文件链接预览 |
UploadFile / UploadLocalFile / TemplateUploader |
上传与文件相关(额外数据源通过 UploadFile 的 sources + #source slot 扩展) |
RichTextEditor |
富文本 |
EchartWrapper |
ECharts 包装 |
QuarterPicker |
季度选择 |
DropdownOperation |
下拉操作 |
FullScreenButton |
全屏按钮 |
K2Frame / K2FrameButton / K2History / K2HistoryDrawer / K2HistoryDrawerButton |
K2 流程相关 |
ElForm / ElTable / ElTableColumn / ElDropdownItem |
对 Element Plus 同名组件的增强包装(会覆盖全局同名注册) |
同名 Element 增强组件会在插件安装时覆盖 Element Plus 的全局组件名。若宿主不需要增强行为,可改为按需引入其它组件,或自行评估是否全局注册这些包装组件。
按需引入
除全局插件外,也可以从主入口按名导入:
<script setup lang="ts">
import { Pagination, UserPicker, SvgIcon } from '@jqms/components_lib'
</script>
<template>
<UserPicker v-model="userIds" />
<Pagination v-model:page="page" v-model:limit="limit" :total="total" />
</template>
即使按需引入单个组件,仍建议:
- 导入
style.css - 合并 i18n
- 调用
createJqmsComponentsPlugin(或至少installJqmsComponentsConfig)注入配置,否则依赖getJqmsComponentsConfig()的组件会报错。
其它导出示例:
import {
createJqmsComponentsPlugin,
elementIcons,
registerJqmsChartThemes,
jqmsComponents,
getJqmsComponentsConfig,
useJqmsComponentsConfig
} from '@jqms/components_lib'
宿主侧额外准备
SvgIcon
name以ele-开头:解析为 Element Plus Icons(需先app.use(elementIcons))。- 其它名称:使用 SVG sprite,引用
#icon-${name}。宿主需自行注册 SVG sprite(例如vite-plugin-svg-icons的virtual:svg-icons-register),并保证图标 id 前缀为icon-。
上传相关
注入 uploadUrl,并保证请求头鉴权可用(组件内部会通过 @jqms/utils 的 token 能力读取登录态)。
图表主题
import { registerJqmsChartThemes } from '@jqms/components_lib'
registerJqmsChartThemes()
TypeScript
包内已提供类型声明:
- 主入口:
@jqms/components_lib→types/index.d.ts - i18n:
@jqms/components_lib/i18n→types/i18n.d.ts
安装插件后,全局组件类型会通过 vue 的 GlobalComponents 扩展。若 IDE 未识别,确认 tsconfig 能解析到包的 types 字段,并重启 TS 服务。
业务应用接入(npm)
业务项目通过 npm 安装已发布版本(推荐):
{
"dependencies": {
"@jqms/components_lib": "^1.1.0",
"@jqms/system_service": "^1.0.0",
"@jqms/utils": "^1.0.2"
}
}
安装 peer 依赖后按本文「接入步骤」配置即可,无需 clone 基础设施仓库或将本包作为 workspace 成员。
仓库内开发联调
本仓库为 前端基础设施管理仓库,packages/jqms_components_lib 为组件库源码。维护者在仓库内开发时可切换 source / dist:
# 指向 src(本地热更新)
pnpm -C packages/jqms_components_lib use:source
# 指向 dist(模拟发布产物)
pnpm -C packages/jqms_components_lib build
pnpm -C packages/jqms_components_lib use:dist
查看当前模式:
pnpm -C packages/jqms_components_lib mode
切换到 dist 后,若 Vite 仍加载旧预构建缓存,请强制重建:
pnpm exec vite --force
常见问题
1. 组件尺寸/间距异常(如图标变大)
未导入样式:
import '@jqms/components_lib/style.css'
2. Cannot access 'xxx' before initialization(i18n 初始化)
从主入口导入了 mergeJqmsComponentsLocales。请改为:
import { mergeJqmsComponentsLocales } from '@jqms/components_lib/i18n'
3. 请求失败 / 接口 404
确认宿主已安装 @jqms/system_service(与组件库 peer 版本兼容),且后端提供对应 API(如 /system/user/list、/mdplantcustomer/list 等)。
4. @jqms/components_lib has not been configured
未调用 createJqmsComponentsPlugin(options),或在插件安装前就渲染了依赖配置的组件。
5. ElDropdown 递归更新 / TSX 行为异常(仅 dist)
组件库构建必须启用 @vitejs/plugin-vue-jsx。已发布包已包含正确构建配置;若自行 fork 构建,请确认 Vite 插件包含 Vue JSX。
6. 业务项目应使用 npm 版本而非仓库路径
检查业务项目 package.json:
- 依赖应为 semver 版本号(如
^1.1.0),而非workspace:^或file: node_modules/@jqms/components_lib应来自 npm registry,而非指向本基础设施仓库
维护者:构建与发布
cd packages/jqms_components_lib
# 构建主包 + 独立 i18n 入口
pnpm build
# 发布前会自动:build → use:dist
pnpm publish
# 发布后会自动切回 source
构建产物:
| 文件 | 用途 |
|---|---|
dist/jqms-components-lib.js |
ESM 主包 |
dist/jqms-components-lib.umd.cjs |
UMD |
dist/jqms-components-lib-i18n.js |
独立 i18n 入口 |
dist/style.css |
组件样式 |
dist 目录建议加入 .gitignore,由 prepublishOnly 在发布时生成,不必提交到 Git。
导出子路径一览
| 导入路径 | 内容 |
|---|---|
@jqms/components_lib |
组件、插件、配置、注册表等 |
@jqms/components_lib/i18n |
mergeJqmsComponentsLocales、jqmsComponentsLocales |
@jqms/components_lib/style.css |
组件样式 |
完整最小示例
// main.ts
import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import '@jqms/components_lib/style.css'
import {
createJqmsComponentsPlugin,
elementIcons,
registerJqmsChartThemes
} from '@jqms/components_lib'
import { mergeJqmsComponentsLocales } from '@jqms/components_lib/i18n'
import App from './App.vue'
const i18n = createI18n({
legacy: false,
locale: 'zh-cn',
fallbackLocale: 'zh-cn',
messages: { 'zh-cn': {}, 'zh-tw': {}, en: {} }
})
mergeJqmsComponentsLocales((locale, messages) => {
i18n.global.mergeLocaleMessage(locale, messages)
})
const app = createApp(App)
registerJqmsChartThemes()
app.use(ElementPlus).use(elementIcons).use(i18n).use(
createJqmsComponentsPlugin({
t: i18n.global.t,
getLanguage: () => String(i18n.global.locale.value),
getCurrentUser: () => ({}),
getSideTheme: () => 'theme-light',
getIndustrialMode: () => false,
getDictionary: () => ({
getDictsFun: () => [],
getComputedDict: () => [],
getDictLabel: () => ''
}),
k2ServiceUrl: import.meta.env.VITE_APP_K2_SERVICE,
uploadUrl: import.meta.env.VITE_APP_BASE_API + import.meta.env.VITE_APP_UPLOAD_URL
})
)
app.mount('#app')
按上述步骤完成后,即可在页面中使用组件库提供的业务组件。若接入过程中遇到具体组件 props / 事件问题,可直接查看 src/components 下对应源码或联系组件库维护者。
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 1.1.15 | ^3.5.6 | ||
| 1.1.13 | ^3.5.6 | ||
| 1.1.12 | ^3.5.6 | ||
| 1.1.11 | ^3.5.6 | ||
| 1.1.10 | ^3.5.6 | ||
| 1.1.9 | ^3.5.6 | ||
| 1.1.8 | ^3.5.6 | ||
| 1.1.7 | ^3.5.6 | ||
| 1.1.6 | ^3.5.6 | ||
| 1.1.5 | ^3.5.6 | ||
| 1.1.4 | ^3.5.6 | ||
| 1.1.3 | ^3.5.6 | ||
| 1.1.2 | ^3.5.6 | ||
| 1.1.1 | ^3.5.6 | ||
| 1.1.0 | ^3.5.6 | ||
| 1.0.4 | ^3.5.6 | ||
| 1.0.2 | ^3.5.6 | ||
| 1.0.1 | ^3.5.6 | ||
| 1.0.0 | ^3.5.6 |