common-utils-kit
v1.1.40
Published
`common-utils-kit` 是一个基于 Vue 2 和 Element UI 的公共能力包,当前同时提供:
Downloads
645
Readme
Common Utils Kit
common-utils-kit 是一个基于 Vue 2 和 Element UI 的公共能力包,当前同时提供:
- 通用工具方法
- 自定义指令
- 请求封装
- WebSocket 封装
- Element UI 业务组件
当前版本:1.1.39
安装
npm install common-utils-kit依赖要求:
vue2.xelement-ui>=2.13.2
目录能力
主入口
主入口 common-utils-kit 当前导出:
default:Vue 插件入口,支持Vue.use(CommonUtilsKit)挂载$kit并注册公共指令testformattoolfileconfirmrequestwebsockettabledirective
import {
test,
format,
tool,
file,
confirm,
request,
websocket,
table,
directive,
} from 'common-utils-kit';Element 组件入口
common-utils-kit/element 当前导出:
View3DScreenScaleConfirmDialogElementFormElementTableScrollTableResetDrawerResetDialog
import {
View3D,
ScreenScale,
ConfirmDialog,
ElementForm,
ElementTable,
ScrollTable,
ResetDrawer,
ResetDialog,
} from 'common-utils-kit/element';样式
import 'common-utils-kit/lib/utils-kit.css';快速开始
1. 通过 Vue.use 挂载常用能力
import Vue from 'vue';
import CommonUtilsKit from 'common-utils-kit';
Vue.use(CommonUtilsKit);安装后会在 Vue.prototype 上挂载 $kit,并自动注册 directive 中的全局指令:
this.$kit.format.getProperty(data, 'user.name');
this.$kit.table.sortMergeData(list, 'region');
this.$kit.confirm.customConfirm({ title: '提示', toolTips: '确认执行当前操作?' });2. 局部使用
import { confirm, table } from 'common-utils-kit';
confirm.customConfirm({ title: '提示', toolTips: '确认执行当前操作?' });
const sorted = table.sortMergeData(list, 'region');工具能力
test
常用校验能力:
hasValuevalueTypeemailmobileurlidCardcarNoamountchineseletterlandlinecode
import { test } from 'common-utils-kit';
test.email('[email protected]');
test.mobile('13800138000');format
常用数据处理能力:
getPropertyunrepeatedtreeToFlatflatToTreerecursionFunctionfilterDatadateDiffgetNowDatesetFormColumnsData
import { format } from 'common-utils-kit';
const flatList = format.treeToFlat(treeData);
const treeData = format.flatToTree(list);tool
提供:
debouncethrottlesleep
import { tool } from 'common-utils-kit';
await tool.debounce(500);
console.log('submit');
await tool.throttle(500);
console.log('throttle submit');file
提供:
downloadBase64FiledownloadFilesfileToBase64base64ToFilebase64ToFileBlobuploadCompress
import { file } from 'common-utils-kit';
file.downloadFiles('https://example.com/demo.pdf', 'demo.pdf');confirm
当前主用方法是 customConfirm,统一从主入口使用,不再从 element-ui 目录单独引用。
import { confirm } from 'common-utils-kit';
const res = await confirm.customConfirm({
title: '操作确认',
toolTips: '确认执行当前操作?',
titleIcon: 'el-icon-warning-outline',
tipIcon: 'el-icon-warning',
});
console.log(res.flag);输入弹窗示例:
const res = await confirm.customConfirm({
title: '填写原因',
dialogType: 'input',
toolTips: '请输入本次操作原因',
inputPlaceholder: '请输入原因',
inputValue: '',
});
console.log(res.flag, res.inputValue);常用参数:
titledialogTypetoolTipsinputValueinputPlaceholderbtnParamcloseOnClickModalcloseOnPressEscapecustomClasstitleIcontipIcon
request
请求封装从 request 模块获取。
import { request } from 'common-utils-kit';
const http = new request.RequestHttp({
baseURL: '/api',
timeout: 60000,
withCredentials: true,
}, {
getToken: () => localStorage.getItem('token'),
tokenHeader: 'token',
codeKey: 'code',
successCode: 200,
overdueCode: 401,
repeat: 'latest',
showLoading: () => {},
hideLoading: () => {},
handleBusinessError(data, response) {
const messageMap = {
401: '登录已过期,请重新登录',
403: '暂无权限访问',
500: '服务异常,请稍后重试',
};
Message.error(messageMap[data.code] || data.msg || '请求失败');
return Promise.reject(data);
},
handleHttpError(error) {
const status = error.response && error.response.status;
const messageMap = {
400: '请求参数错误',
401: '登录已过期,请重新登录',
404: '接口不存在',
500: '服务器异常',
};
Message.error(messageMap[status] || error.message || '请求失败');
return Promise.reject(error);
},
});
http.request({ method: 'get', url: '/user/info', params: { id: 1 } });
http.get('/user/info', { id: 1 }, { cancel: true, loading: false });
http.post('/user/save', { name: '张三' });模块公开能力:
RequestHttp:可实例化请求类。createRequest(requestConfig, options):函数式创建RequestHttp实例。requestEnum:默认响应码配置,包含SUCCESS、OVERDUE、TIMEOUT。AxiosCanceler:请求取消管理类。getPendingUrl(config):按requestKey或请求方法、地址、参数生成重复请求标识。
状态码处理说明:
codeKey用于配置后端业务状态码字段,默认是code,例如后端返回status时可传codeKey: 'status'。successCode/overdueCode支持0、false等有效值,不会被默认值覆盖。requireCode: true时,响应体没有codeKey指定字段会以ERR_MISSING_RESPONSE_CODE拒绝。- 响应体为
null或undefined时会以ERR_EMPTY_RESPONSE拒绝,避免把异常空响应当成功。 handleBusinessError(data, response)用于自定义后端业务状态码逻辑。handleHttpError(error)用于自定义 HTTP 错误、网络错误、超时等异常逻辑。RequestHttp不内置任何状态码提示文案;未传入错误处理函数时,只会将错误原样Promise.reject给使用方。- 多个请求同时开启 loading 时,内部会维护实例级
loadingCount;只有第一个请求触发showLoading,全部请求结束后才触发hideLoading。
重复请求和竞态处理:
// 查询类:只保留同一 requestKey 的最后一次结果,旧响应晚返回时会以 ERR_STALE_REQUEST 拒绝。
http.get('/order/list', { tab: 2 }, {
requestKey: 'order-list-tab',
repeat: 'latest',
});
// 分页类:pageNum 每次变化,但忽略 pageNum 后仍归为同一类请求。
http.get('/order/list', { pageNum: 2, pageSize: 10 }, {
repeat: 'latest',
repeatIgnoreParams: ['pageNum'],
});
// 操作类:第一个请求完成前拒绝重复提交,第二次请求会以 ERR_DUPLICATE_REQUEST 拒绝。
http.post('/order/next-step', { id: 1 }, {
requestKey: 'order-next-step',
repeat: 'first',
});
// 不处理重复请求。
http.get('/log/list', {}, {
repeat: 'none',
});
请求取消能力:
import { request } from 'common-utils-kit';
const canceler = new request.AxiosCanceler({ type: 'abort' });
const config = {
method: 'get',
url: '/api/list',
requestKey: 'list-page-query',
params: { pageNum: 1 },
};
canceler.addPending(config);
canceler.removePending(config);
canceler.removeAllPending();示例工程中的延迟 mock 请求:
// 先创建并保存请求实例。
let loadingInstance = null;
const http = new request.RequestHttp({}, {
showLoading: () => {
loadingInstance = this.$loading({ text: '请求加载中...' });
},
hideLoading: () => {
loadingInstance && loadingInstance.close();
loadingInstance = null;
},
handleBusinessError: data => {
this.$message.error(data.msg || '业务请求失败');
return Promise.reject(data);
},
handleHttpError: error => {
this.$message.error(error.message || 'HTTP 请求失败');
return Promise.reject(error);
},
});
// 后续请求复用同一个实例,便于观察 repeat 策略。
http.get('/mock/request-list', {
pageNum: currentPage,
pageSize: 10,
}, {
loading: false,
repeat: 'latest',
repeatIgnoreParams: ['pageNum'],
});example/views/request.vue 中的请求示例需要先点击 创建请求实例 保存 RequestHttp 实例,后续 latest 只认最后一次、first 阻止重复、none 全部发出 三个按钮都复用该实例请求 vue.config.js 注册的 /mock/request-list 本地接口。本地 mock 示例不配置 baseURL,避免请求地址变成 /api/mock/request-list。接口延迟 2 秒返回;浏览器 Network 面板可以看到 pending 请求。示例里的 pageNum 每次变化,但通过 repeatIgnoreParams: ['pageNum'] 忽略页码字段,仍归为同一类请求,便于对比重复请求处理效果。
repeat: 'latest':连续点击时,后一次会取消同 key 下前一次未完成请求。repeat: 'first':第一个同 key 请求未结束前,后续点击会直接拒绝。repeat: 'none':不处理重复请求,连续点击会连续发出请求。
示例页还提供这些可点击按钮,都会请求 vue.config.js 中注册的本地 mock 接口。RequestHttp 本身不内置 UI 提示,示例页通过注入的 handleBusinessError / handleHttpError 调用 Element UI 的 $message.error,通过 showLoading / hideLoading 调用 $loading 服务展示并关闭加载动画:
handleBusinessError:请求/mock/request-business-error,接口返回业务失败码,进入handleBusinessError(data, response)。handleHttpError:请求/mock/request-http-error,接口返回 HTTP 500,进入handleHttpError(error)。showLoading/hideLoading:请求/mock/request-loading,展示 Element UI loading 动画、实例级 loading 计数和回调触发顺序。transformResponse:请求/mock/request-transform,通过独立实例的transformResponse(response)转换响应数据。requireCode 缺少 code:请求/mock/request-no-code,通过requireCode: true展示ERR_MISSING_RESPONSE_CODE,并在示例页 catch 中调用$message.error。removeAllPending 手动取消:请求/mock/request-cancel后调用axiosCanceler.removeAllPending(),Network 面板可看到取消请求,结果里展示ERR_CANCELED。
websocket
import { websocket } from 'common-utils-kit';
const client = websocket.createSocketClient({
url: 'ws://example.com/socket',
heartMessage: 'ping',
heartTime: 60000,
reconnectTime: 5000,
onMessage: event => console.log(event.data),
});
client.connect();
client.send({ type: 'hello' });
client.close();table
当前主用场景是 Element 表格合并行辅助。
import { table } from 'common-utils-kit';
const sorted = table.sortMergeData(sourceData, 'region');
const spanList = table.getMergeSpanList(sorted, 'region');
const spanMethod = table.createMergeSpanMethod(spanList, 0);指令
通过 Vue.use(directive) 安装后,当前可用指令包括:
v-debouncev-input-debouncev-btn-debouncev-btn-throttlev-click-lockv-relative-timev-input-rulev-local-loadingv-full-loadingv-el-drag-dialog
示例:
<template>
<div>
<el-input
v-model="keyword"
v-input-debounce:1000="handleSearch"
placeholder="输入后防抖搜索"
/>
<el-button v-btn-throttle="500" @click="handleSubmit">
节流提交
</el-button>
</div>
</template>Element 组件
ConfirmDialog
ConfirmDialog 是一个基于 el-dialog 的业务确认弹窗组件。
<template>
<confirm-dialog
v-model="dialogVisible"
title="删除提示"
dialog-type="tips"
tool-tips="删除后数据不可恢复,是否继续?"
:btn-param="componentBtns"
title-icon="el-icon-warning-outline"
tip-icon="el-icon-warning"
@affirm="handleConfirm"
/>
</template>
<script>
import { ConfirmDialog } from 'common-utils-kit/element';
export default {
components: {
ConfirmDialog,
},
data() {
return {
dialogVisible: false,
componentBtns: [
{ btnlable: '取消', type: '', flag: 'cancel' },
{ btnlable: '确认删除', type: 'danger', flag: 'confirm' },
],
};
},
methods: {
handleConfirm(flag, value) {
console.log(flag, value);
this.dialogVisible = false;
},
},
};
</script>ElementForm
ElementForm 是配置型表单/展示组件。
基础用法
<template>
<element-form
ref="formExample"
:columns="formColumns"
:form-data="formData"
:label-width="110"
:value-width="90"
@itemChange="itemChange"
@handleSearch="handleSearch"
@handleClear="handleClear"
/>
</template>
<script>
import { ElementForm } from 'common-utils-kit/element';
export default {
components: {
ElementForm,
},
data() {
return {
formData: {
customerName: '',
customerType: '',
},
formColumns: [
{
param: 'customerName',
label: '客户名称',
effect: 'form',
type: 'search',
rules: { required: true },
proport: 8,
},
{
param: 'customerType',
label: '客户类型',
effect: 'form',
type: 'select',
props: { label: 'label', value: 'value' },
data: [],
rules: { select: true },
proport: 8,
},
],
};
},
};
</script>通过 ref 批量填充列配置
batchSetColumnData 现在通过组件实例方法提供,不需要再从内部 utils/common.js 直接引用。
created() {
this.formColumns = this.createFormColumns();
},
mounted() {
this.formColumns = this.$refs.formExample.batchSetColumnData({
客户类型: [
{ label: '企业客户', value: 'company' },
{ label: '个人客户', value: 'personal' },
],
客户标签: [
{ label: '重点客户', value: 'important' },
{ label: '已签约', value: 'contract' },
{ label: '待跟进', value: 'follow' },
],
}, { unique: 'label', data: 'data' });
}组件实例方法
submitForm():执行表单校验,返回BooleanclearValidate(param):清空校验batchSetColumnData(config, props):基于当前columns返回新的列配置setFormDisabled(disabled, params):批量设置表单项禁用状态
常见字段
paramlabeleffecttyperulesproportpropsdataclearablefilterablemultipledisabled
支持的常见类型
inputselectcascaderdatecheckboxradiotextareasearch
ElementTable
ElementTable 是配置型表格组件,支持:
- 复选列
- 单选列
- 序号列
- 详情跳转列
- 开关列
- 图片列
- 按钮列
- 分隔展示
- 拼接展示
- 气泡提示
- 气泡表格
- 表头插槽
- 单元格插槽
<template>
<element-table
:columns="columns"
:main-data="tableData"
:show-checkbox="true"
:show-radio="true"
:select-radio.sync="selectRadio"
:show-index="true"
:page="page"
row-key="id"
@handleButton="handleButton"
@setStatus="setStatus"
@openDetail="openDetail"
/>
</template>
<script>
import { ElementTable } from 'common-utils-kit/element';
export default {
components: {
ElementTable,
},
};
</script>ScrollTable
滚动加载表格组件:
<template>
<scroll-table
:columns="columns"
:main-data="tableData"
:loading="loading"
:finished="finished"
height="460"
@load="loadMore"
/>
</template>
<script>
import { ScrollTable } from 'common-utils-kit/element';
export default {
components: {
ScrollTable,
},
};
</script>常用参数:
columnsmainDataloadingfinishedloadDistanceheight
ScreenScale
大屏缩放容器:
<template>
<screen-scale :width="1920" :height="1080">
<div style="width: 1920px; height: 1080px;">
大屏内容
</div>
</screen-scale>
</template>
<script>
import { ScreenScale } from 'common-utils-kit/element';
export default {
components: {
ScreenScale,
},
};
</script>ResetDrawer
用于解决业务抽屉外层直接 v-if 销毁时,append-to-body 挂载异常的问题。
<template>
<reset-drawer
v-model="drawerVisible"
title="业务抽屉"
size="480px"
:wrapper-closable="false"
>
<business-drawer-content :id="currentId" />
</reset-drawer>
</template>
<script>
import { ResetDrawer } from 'common-utils-kit/element';
export default {
components: {
ResetDrawer,
},
};
</script>ResetDialog
用于解决业务弹窗外层直接 v-if 销毁时,append-to-body 挂载异常的问题。
<template>
<reset-dialog
v-model="dialogVisible"
title="业务弹窗"
width="560px"
:close-on-click-modal="false"
>
<business-dialog-content :id="currentId" />
<template slot="footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false">确定</el-button>
</template>
</reset-dialog>
</template>
<script>
import { ResetDialog } from 'common-utils-kit/element';
export default {
components: {
ResetDialog,
},
};
</script>View3D
View3D 为三维展示组件,当前通过 common-utils-kit/element 兼容导出:
import { View3D } from 'common-utils-kit/element';具体业务参数请结合实际页面或示例工程使用。
本地开发
npm run dev构建
npm run build构建 npm 主入口
npm run lib构建 Element 子入口
npm run lib:module发布前需要同时执行 npm run lib 和 npm run lib:module,确保主入口 common-utils-kit 与组件入口 common-utils-kit/element 都生成对应产物。
检查
npm run lint