@cimom-ui/standard-ui
标准组件库:基于 Vue 2.6 + Element UI 2.x + vxe-table 3.24.x 的通用业务组件,供其它项目复用。
共 14 个顶层组件。StandardForm、StandardFilterbar、StandardTable、StandardTabs 会连带注册子组件。StandardAdvancedQuery 只给筛选栏的「高级查询」使用,不单独暴露。
属性表里的名字是模板写法(kebab-case),与代码里的 camelCase 一一对应,例如 number-only 对应 numberOnly。事件名也是 kebab-case。
安装
npm i @cimom-ui/standard-ui
使用方必须先安装并注册这些依赖:
| 包 | 版本要求 | 说明 |
|---|---|---|
| vue | ^2.6.0 | |
| element-ui | ^2.15.0 | 全部组件依赖,并引入 element-ui/lib/theme-chalk/index.css |
| vxe-table | ^3.24.0 | 仅 StandardTable 依赖,并引入 vxe-table/lib/style.css |
| @vxe-ui/core | ^3.4.24 | vxe-table 3.24 的运行时依赖。本包 dependencies 已声明,随本包安装 |
import Vue from 'vue'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
Vue.use(ElementUI)
Vue.use(VXETable)
组件自身的样式已经打进 JS 产物,使用方不用再引一份组件 css。vxe-table 的样式仍由使用方引入。
注册方法
全局注册(推荐)
入口注册一次后,页面直接写标签,不用再 import。
// src/main.js
import StandardComponents from '@cimom-ui/standard-ui'
import axios from '@/util/api.request'
Vue.use(StandardComponents, {
// 模块编码,和页面编码、表格编码一起定位表头配置
moduleCode: process.env.VUE_APP_MODULE_CODE,
// 业务项目自己的请求方法。接口路径固定,IP 和端口来自该方法的 baseURL
request: (config) => axios.request(config)
})
Vue.use 会注册全部顶层组件,并连带注册这些子组件:
| 父组件 | 一并注册的标签 |
|---|---|
| StandardFilterbar | <standard-filterbar-item> |
| StandardForm | <standard-form-item> |
| StandardTable | <standard-column>、<standard-toolbar-left>、<standard-toolbar-right>、<standard-toolbar-query>、<standard-toolbar-empty>、<standard-footer-left>、<standard-footer-right>、<standard-footer-empty> |
| StandardTabs | <standard-tab-pane> |
局部注册
lib 构建产物只保留默认导出,组件挂在默认导出对象上。子组件挂在父组件的静态属性上。
import StandardComponents from '@cimom-ui/standard-ui'
export default {
components: {
'standard-table': StandardComponents.StandardTable,
'standard-column': StandardComponents.StandardTable.Column,
'standard-toolbar-left': StandardComponents.StandardTable.ToolbarLeft,
'standard-toolbar-right': StandardComponents.StandardTable.ToolbarRight,
'standard-toolbar-query': StandardComponents.StandardTable.ToolbarQuery,
'standard-footer-right': StandardComponents.StandardTable.FooterRight,
'standard-filterbar': StandardComponents.StandardFilterbar,
'standard-filterbar-item': StandardComponents.StandardFilterbar.Item,
'standard-form': StandardComponents.StandardForm,
'standard-form-item': StandardComponents.StandardForm.Item,
'standard-tabs': StandardComponents.StandardTabs,
'standard-tab-pane': StandardComponents.StandardTabs.TabPane
}
}
局部注册不会走库的 install,表头配置的 moduleCode 和 request 不会自动注入。需要「调整」列配置持久化时,使用全局注册。
注意事项
- 先
Vue.use(ElementUI)、Vue.use(VXETable),再注册本库。按钮、输入框、下拉、时间选择内部固定size="mini",页面传size不会改掉。 - 全局注册请带上
moduleCode和request。表格渲染从浏览器本地存储TableSetting读取表头,按「模块编码/页面编码/表格编码」取对应CLAYOUT,不再逐表调用GetConfig。保存和恢复默认仍调用/api/Migration/UserTableColumn/SaveConfig、ResetConfig,成功后回写TableSetting里的对应项。GetConfig不接收模块、页面、表格参数,返回当前用户全部布局,由其它程序调用后写入TableSetting。没传request时不访问服务端,仍可读已有缓存。同一页面里每个表格的table-code必须唯一;不传时用组件ref,ref也没有则不读写配置。page-code不传时用当前路由name,没有name时用去掉查询参数的path。 <standard-filterbar>必须接@search,否则校验失败、整块不渲染,并在控制台输出[StandardFilterbar]错误。筛选值写在传入对象的属性上,运行中不要整体替换searchBar或searchVariable。- 筛选栏默认插槽里只认
<standard-filterbar-item>。插槽项排在searchCondition前面,一个插槽项算一条条件。首行放不下的进「更多」或「高级查询」。isMain可以写在配置里,不再决定谁在首行。 <standard-dialog>的@confirm不关闭弹窗,业务成功后再改v-model。点击遮罩默认不关闭。标题栏默认可拖拽,再次打开回到居中。<standard-toolbar-query>只能放在<standard-toolbar-right>里面。放错位置不渲染,并console.warn。右上角「调整」由<standard-table show-adjustment>控制,默认显示;写在standard-toolbar-right上不生效。<standard-form-item>必须放在<standard-form>里,:span用数字绑定(:span="12")。字符串span="12"不会按栅格计算。- 树形表格同时传
tree-config和row-config。节点列加tree-node。row-config.keyField与tree-config.rowField用同一个字段。 - 页面根节点用
<standard-page>。左右分栏加vertical。拖完分割条后对两侧表格调用recalculate()。 - 弹窗里的表格要给明确高度(例如
style="height: 420px")。表格位于el-dialog内、右键菜单被挡住时,给表格传z-index(大于弹窗层级,如3000),或在使用方执行VXETable.setup({ zIndex: 5000 })。本库install里的zIndex: 5000只作用于打进产物的那份 vxe-table。
组件总览
| 组件 | 标签 | 形态 | 说明 |
|---|---|---|---|
| StandardButton | <standard-button> | 单/双标签 | 标准按钮,固定 mini,其余透传 el-button |
| StandardInput | <standard-input> | 单/双标签 | 标准输入框,自动 trim,可仅数字 |
| StandardSelect | <standard-select> | 单标签 | 标准下拉,单选/多选、远程搜索 |
| StandardTimePick | <standard-time-pick> | 单标签 | 标准时间选择,年月日或年月日时分秒 |
| StandardDialog | <standard-dialog> | 双标签 | 标准弹窗,确定不自动关闭,可拖拽 |
| StandardContainer | <standard-container> | 双标签 | 布局容器,只排方向和尺寸 |
| StandardFilterbar | <standard-filterbar> | 单/双标签 | 筛选栏。子组件 <standard-filterbar-item> |
| StandardForm | <standard-form> | 双标签 | 标准表单。子组件 <standard-form-item> |
| StandardHalfArea | <standard-half-area> | 双标签 | 半区,left / right,可透明 |
| StandardPage | <standard-page> | 双标签 | 页面骨架 |
| StandardSplitter | <standard-splitter> | 单标签 | 左右分割条,px 或 percent |
| StandardTable | <standard-table> | 双标签 | 标准表格。8 个子组件,见下文 |
| StandardTabs | <standard-tabs> | 双标签 | 标准页签。子组件 <standard-tab-pane> |
| StandardTree | <standard-tree> | 单标签 | 标准树,搜索、节点、底部展开收起 |
组件说明
StandardButton 标准按钮
单标签用 label,双标签用默认插槽。插槽有内容时优先于 label。内部固定 size="mini"。loading、disabled、@click 等透传 el-button。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | String | '' | 按钮文案 |
| icon | String | '' | 图标类名,如 el-icon-search |
| type | String | '' | primary / success / warning / danger / info / text |
插槽:默认插槽,按钮文案。
<standard-button label="查询" type="primary" icon="el-icon-search" :loading="loading" @click="onSearch" />
<standard-button type="danger" @click="onDelete">删除</standard-button>
StandardInput 标准输入框
v-model 绑值,输入时自动 trim。内部固定 size="mini"、可清空,宽度 175px。class、disabled、@focus、@blur、@clear 等透传。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String / Number | '' | v-model |
| placeholder | String | '请输入' | 占位文案 |
| number-only | Boolean | false | 只保留 0-9 |
事件:@input(v-model)、@enter(回车)。其余透传。
插槽:
| 插槽 | 说明 |
|---|---|
| 默认插槽 | 输入框右侧附加内容(el-input 的 append),常用于单位 |
| prepend | 左侧附加 |
| prefix | 前缀图标位 |
| suffix | 后缀图标位 |
<standard-input v-model="keyword" placeholder="请输入关键字" @enter="onSearch" />
<standard-input v-model="form.qty" number-only>个</standard-input>
StandardSelect 标准下拉
单选绑定任意值。multiple 时绑定值必须是数组,组件会兜底成 []。内部固定 size="mini"、可清空,宽度 175px。远程模式强制 filterable 和 reserve-keyword。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String / Number / Array | '' | v-model |
| options | Array | [] | 静态选项。[{ label, value }],或配 option-props 的对象数组,也接受 ['A','B'] |
| option-props | Object | { label: 'label', value: 'value' } | 选项字段映射 |
| remote | String / Function | '' | 远程方法。函数直接调用;字符串沿父组件链找同名方法。入参为关键字 |
| multiple | Boolean | false | 多选 |
| filterable | Boolean | true | 可筛选。远程模式强制开启 |
| clearable | Boolean | true | 可清空 |
| disabled | Boolean | false | 禁用 |
| placeholder | String | '请选择' | 占位文案 |
事件:@input、@change、@visible-change。其余透传 el-select。
插槽:默认插槽,写在自动生成的 el-option 之后,可追加选项。
远程方法返回 Promise。返回值可以是数组,或带 Datas / data / data.Datas / list 的响应。组件防抖 300ms,自己管 loading,首次挂载以及下拉展开且没有数据时会拉取。
<standard-select v-model="form.type" :options="typeOptions" />
<standard-select v-model="form.types" multiple :options="typeOptions" />
<standard-select
v-model="form.deptId"
remote="remoteDeptList"
:option-props="{ label: 'DEPT_NAME', value: 'DEPT_ID' }"
placeholder="请选择部门"
/>
StandardTimePick 标准时间选择
type 只认 date(默认,年月日)和 datetime(年月日时分秒)。内部固定 size="mini"、可清空、弹出面板右对齐,宽度 175px。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String / Date / Array | '' | v-model |
| type | String | 'date' | date / datetime |
| value-format | String | '' | 不传时按类型用 yyyy-MM-dd 或 yyyy-MM-dd HH:mm:ss |
| placeholder | String | '' | 不传时为「请选择日期」或「请选择时间」 |
| clearable | Boolean | true | 可清空 |
| disabled | Boolean | false | 禁用 |
| picker-options | Object | null | 同 el-date-picker 的 picker-options |
事件:@input。其余透传。无插槽。
<standard-time-pick v-model="form.checkDate" />
<standard-time-pick v-model="form.checkTime" type="datetime" />
StandardDialog 标准弹窗
双标签。v-model 控制显隐。宽度随内容撑开,最小 300px,最宽 80vw;最高 80vh,超出后内容区内部滚动。底部按钮固定为「取消」「确定」,都是 mini。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| visible | Boolean | false | v-model |
| title | String | '' | 标题 |
| show-cancel | Boolean | true | 显示取消 |
| show-confirm | Boolean | true | 显示确定 |
| confirm-loading | Boolean | false | 确定按钮加载态 |
| close-on-click-modal | Boolean | false | 点击遮罩是否关闭。默认关闭,需要时传 true |
| draggable | Boolean | true | 按住标题栏拖动。全屏时不拖。传 false 关闭 |
| show-fullscreen | Boolean | false | 关闭按钮左侧显示全屏切换 |
| default-fullscreen | Boolean | false | 打开即全屏,并固定显示全屏按钮。关闭再打开恢复全屏 |
| fullscreen | Boolean | false | 打开时的初始全屏。不强制显示切换按钮 |
width、append-to-body、show-close、custom-class 等经 $attrs 传给 el-dialog。
事件:
| 事件 | 说明 |
|---|---|
@confirm | 点击确定。不关闭弹窗 |
@cancel | 点击取消,并关闭 |
@close | 右上角关闭,透传 el-dialog |
@update:visible | v-model |
@update:fullscreen | 全屏状态变化 |
插槽:默认插槽,弹窗内容。标题和底部按钮不开放插槽。
<standard-dialog v-model="visible" title="新增" :confirm-loading="saving" @confirm="submit" @close="close">
<standard-form ref="editForm" :model="form" :rules="rules"><!-- 表单项 --></standard-form>
</standard-dialog>
StandardContainer 标准布局容器
双标签。没有边框、背景和内边距,只负责方向和尺寸。子项不放大、不压缩,交叉轴拉伸填满。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| direction | String | 'column' | column 纵向 / row 横向 |
| size | Number | 100 | 占父容器主轴的百分比,0–100。父级是纵向容器时作用于高度,横向时作用于宽度。顶层容器按纵向处理 |
| height | Number / String | null | 显式高度。数字按 px。优先级高于 size |
| width | Number / String | null | 显式宽度。数字按 px。优先级高于 size |
插槽:默认插槽。
放进弹窗时,百分比要生效,顶层容器需要显式高度或宽度。
<standard-container direction="row" width="400px">
<standard-container><!-- 左 --></standard-container>
<standard-container><!-- 右 --></standard-container>
</standard-container>
StandardFilterbar 标准筛选栏
单标签靠 v-model 配条件;双标签时,默认插槽里的 <standard-filterbar-item> 排在配置条件之前。首行按容器宽度排布,单项宽在 175–300px。放不下的进「更多」。show-advanced-query 时改为「高级查询」弹层,不再展开次行。
v-model 绑定:
searchBar: {
searchCondition: [], // 条件配置,可省略
searchVariable: {}, // 键必须覆盖每条条件的 value,初始值就是重置目标
mainConditionCount // 可选。首行条数上限。不传则只受宽度限制
}
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| search-bar | Object | 必填 | v-model |
| show-export | Boolean | false | 显示「导出」 |
| show-expand | Boolean | true | 显示「更多」。false 时未进首行的条件换行常显 |
| show-advanced-query | Boolean | false | 用「高级查询」代替「更多」 |
| expand-upwards | Boolean | true | 「更多」向上展开。高级查询模式下无效 |
| loading | Boolean | false | 查询按钮加载态 |
| reset-trigger-search | Boolean | false | 重置后自动再派发 @search |
事件:
| 事件 | 说明 |
|---|---|
@search | 必接。查询按钮、文本回车、高级查询确定都会派发 |
@export | 点击导出。需 show-export |
@reset | 已恢复为创建时的初始值 |
@render-error | 校验失败,参数为错误信息数组 |
插槽:默认插槽。只收集 <standard-filterbar-item>,其它节点忽略。
条件 type:
| type | 控件 | 说明 |
|---|---|---|
text | el-input | 回车即查询,值会 trim |
date | el-date-picker | yyyy-MM-dd |
datetime | el-date-picker | yyyy-MM-dd HH:mm:ss |
select | el-select | selectSource 或 remote |
select-multi | el-select 多选 | 绑定值必须是数组 |
条件字段:label、value(必填,且必须已存在于 searchVariable)、type(必填)。可选 placeholder、clearable(默认 true)、width(数字 px 或 CSS 宽度)、selectSource、remote(函数或父组件方法名)、optionProps: { label, value }。远程返回值约定与 standard-select 相同,防抖 300ms。
<standard-filterbar
v-model="searchBar"
show-export
reset-trigger-search
:loading="loading"
@search="onSearch"
@export="onExport"
>
<standard-filterbar-item label="车间">
<el-select v-model="extra.workshop" size="mini" clearable placeholder="请选择车间" />
</standard-filterbar-item>
</standard-filterbar>
searchBar: {
searchCondition: [
{ label: '开始时间', value: 'startTime', type: 'datetime', clearable: false },
{ label: '关键字', value: 'keyword', type: 'text', placeholder: '请输入关键字' },
{ label: '部门', value: 'deptId', type: 'select', remote: 'remoteDeptList',
optionProps: { label: 'DEPT_NAME', value: 'DEPT_ID' } },
{ label: '状态', value: 'status', type: 'select',
selectSource: [{ label: '全部', value: '-1' }, { label: '启用', value: '1' }] }
],
searchVariable: { startTime: '', keyword: '', deptId: '', status: '-1' }
}
插槽里的控件不进 searchVariable,重置按钮不会清它们。需要联动清空时听 @reset。
子组件 StandardFilterbarItem
放在 <standard-filterbar> 默认插槽里。标题在上、控件在下。一个组件算一条条件。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | String | '' | 标题 |
| width | Number / String | null | 自定义宽度。不传则跟随首行统一宽度 |
| layout-width | Number | 0 | 筛选栏测量后写入,页面不要传 |
插槽:默认插槽,放具体控件(el-select、el-input、standard-input 等)。
StandardForm / StandardFormItem 标准表单
双标签。label 宽度按全部表单项里最长的 label 计算:中文 15px/字 + 英文 10px/字 + 40px。控件尺寸默认 mini。表单项内控件样式为宽度 100%。
StandardForm
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| model | Object | {} | 表单数据。可用 :model,也支持 v-model(update:model) |
| rules | Object | null | 同 el-form |
| size | String | 'mini' | 控件尺寸 |
| label-position | String | 'right' | left / right / top |
| width | Number / String | null | 表单宽度。数字按 px。不传则撑满父级 |
label-width 由组件计算,不要再传。其余属性、事件透传 el-form。
对外方法(ref):validate、resetFields、clearValidate。
插槽:默认插槽,放 <standard-form-item>。
StandardFormItem
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| label | String | '' | 标签,参与 label 宽度计算 |
| prop | String | '' | 校验字段,对应 rules 的 key |
| span | Number | 24 | 栅格 1–24。半行并排写 :span="12" |
required 等其余属性透传 el-form-item。
插槽:默认插槽,放输入控件。
<standard-form ref="editForm" :model="form" :rules="rules" width="600px">
<standard-form-item label="名称" prop="NAME" :span="12">
<standard-input v-model="form.NAME" placeholder="请输入名称" />
</standard-form-item>
<standard-form-item label="备注">
<el-input v-model.trim="form.REMARK" type="textarea" :rows="3" />
</standard-form-item>
</standard-form>
StandardHalfArea 标准半区
双标签。默认是白底圆角卡片。左右分栏时和 <standard-splitter> 一起放在 <standard-page vertical> 里。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| left | Boolean | false | 左半区,flex: 0 0 auto,宽度由页面用 style 指定 |
| right | Boolean | false | 右半区,flex: 1 1 0% 占满剩余宽度 |
| transparent | Boolean | false | 去掉卡片外观,只留布局。内部筛选栏、表格、树自己带卡片时使用 |
插槽:默认插槽。
<standard-half-area left :style="{ width: leftWidth + 'px' }"><!-- 左 --></standard-half-area>
<standard-splitter v-model="leftWidth" />
<standard-half-area right><!-- 右 --></standard-half-area>
StandardPage 标准页面骨架
双标签。自带 16px 内边距(宽度 ≤768px 时 12px)、白底、overflow: hidden、纵向 flex。页面本身不出现滚动条,滚动发生在表格等内容区。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| client | Boolean | false | true 时高度 calc(100vh - 29px),否则 calc(100vh - 135px) |
| vertical | Boolean | false | 内容放进横向 flex 层,用于左树/左表 + 右内容 |
插槽:默认插槽,放筛选区、半区、表格、弹窗。
<standard-page :client="isClient">
<standard-filterbar v-model="searchBar" @search="onSearch" />
<standard-table :table-data="tableData" />
</standard-page>
StandardSplitter 标准分割条
单标签。拖拽改变左侧宽度。拖拽中禁止选中文字。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | Number | 260 | v-model,左侧宽度 |
| unit | String | 'px' | px / percent |
| min-width | Number | 200 | px 模式最小宽度 |
| max-ratio | Number | 0.6 | px 模式最大占父容器比例 |
| min-pixel | Number | 320 | percent 模式两侧最小像素 |
| max-half-percent | Number | 45 | percent 模式单侧百分比上限 |
事件:@input(拖拽中)、@drag-start、@drag-end、@change(后两个在松手时派发,参数为最终宽度)。无插槽。
联动页在 @drag-end 里对两侧表格调用 recalculate()。
StandardTable 标准表格
双标签,基于 vxe-table。数据用 table-data,操作列用 table-operation。工具栏、分页、列都在默认插槽里声明,由表格拿到对应区域渲染。列组件本身不占布局。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| table-data | Array | [] | 表格数据 |
| table-operation | Array | [] | 操作列。见下方按钮项 |
| loading | Boolean | false | 加载态 |
| height | String / Number | '100%' | 表格高度 |
| show-footer | Boolean | false | 底部栏。出现 standard-footer-left 或 standard-footer-right 时自动显示 |
| show-update-time | Boolean | true | 底部左侧「数据更新时间」。只在 show-footer 为 true、且没有 footer-left 子组件和 footer-left 插槽时显示 |
| show-checkbox | Boolean | false | 首列多选 |
| show-adjustment | Boolean | true | 右上角「调整」列设置。传 false 隐藏 |
| show-context-menu | Boolean | false | 单元格右键菜单。默认不拦截,走浏览器菜单。表头右键(排序、固定列)不受此开关影响 |
| footer-method | Function | null | 表尾合计,原样交给 vxe-table |
| menu-config | Object | null | 自定义右键菜单,原样交给 vxe-table。传入后不再使用内置菜单 |
| tree-config | Object | null | 树形配置,原样透传 |
| row-config | Object | null | 行主键。树表写 { keyField: 'id' } |
| edit-config | Object / Boolean | null | 不传时,只要有列开了编辑,就按点击单元格编辑。false 关闭。对象原样交给 vxe-table |
| z-index | Number | null | 右键菜单、tooltip 的层级 |
| table-code | String | '' | 表头配置里的表格编码。不传用 ref |
| page-code | String | '' | 表头配置里的页面编码。不传用路由 |
操作列每一项:
| 字段 | 说明 |
|---|---|
| text | 按钮文字 |
| method | 函数,或父组件方法名。入参 (row, btn) |
| active | true / false,或函数 (row, btn)。false 时按钮禁用,不隐藏 |
| width | 参与操作列宽度合计,未写按 60px 估算 |
| color | 文字颜色。删除常用 #f56c6c |
按钮不超过 3 个时全部显示。超过 3 个时前 3 个直出,其余进「更多」。
事件:
| 事件 | 说明 |
|---|---|
@current-change | 当前行变化,参数为 vxe-table 的参数 |
@selection-change | 多选变化,参数为已选行数组 |
@toggle-tree-expand | 树节点展开/收起 |
@op-click | 操作列点击,参数 (row, btn) |
@menu-click | 右键菜单点击,参数为 vxe-table 的参数 |
@edit-activated / @edit-closed | 单元格编辑开始 / 结束 |
未传 menu-config 且 show-context-menu 为 true 时,单元格菜单为「复制」加上操作列按钮。
对外方法(ref):
| 方法 | 说明 |
|---|---|
recalculate() | 容器尺寸变化后重算布局 |
setAllTreeExpand(expanded) | 树表全部展开或收起 |
getSelection() | 已勾选行 |
clearSelection() | 清空勾选 |
setCurrentRow(row) | 勾选某一行(多选) |
setCurrentRecord(row) | 设为当前高亮行,不触发 current-change |
exportData(options) | 转调 vxe-table 的 exportData |
插槽:
| 插槽 | 说明 |
|---|---|
| 默认插槽 | 放下面的子组件。工具栏、分页、列会被抽到对应区域 |
| footer-left | 底部栏左侧自定义内容。仅当 show-footer 为 true,且没有 <standard-footer-left> 时显示 |
子组件 StandardToolbarLeft
放在 <standard-table> 默认插槽内,渲染到操作区左侧。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| buttons | Array | [] | { type, icon, text, title, method, show }。method 为函数或父组件方法名,入参为按钮对象。show: false 不渲染 |
事件:@toolbar-click,参数为按钮对象。
插槽:默认插槽,和 buttons 一起显示。插槽里的按钮自己绑事件。
子组件 StandardToolbarRight
放在 <standard-table> 默认插槽内,渲染到操作区右侧、「调整」按钮之前。
无需要页面传入的属性。插槽:默认插槽,放按钮或 <standard-toolbar-query>。
子组件 StandardToolbarQuery
只能作为 <standard-toolbar-right> 的子组件。从左到右是输入框、查询;show-export 时再加导出。间距 6px。回车与点击查询相同。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String / Number | '' | v-model,查询关键字 |
| placeholder | String | '请输入关键字' | 占位 |
| query-method | Function / String | '' | 查询方法,入参为当前关键字 |
| export-method | Function / String | '' | 导出方法,约定同上。需 show-export |
| show-export | Boolean | false | 显示导出 |
| loading | Boolean | false | 查询按钮加载态 |
事件:@input、@query、@export。后两个参数都是当前关键字。传了 method 仍会派发事件。无插槽。
子组件 StandardToolbarEmpty
操作区没有任何左右工具栏时,表格会自己留出一块 10px 间距。页面一般不用写。写了 <standard-toolbar-empty /> 也是同一块占位。左右工具栏有其一则不占位。无属性、无插槽。
子组件 StandardColumn
声明列,必须放在 <standard-table> 内(可以隔着 tabs 等中间层)。自身不显示。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| field | String | '' | 字段名。与 type 至少给一个 |
| column-key | String | '' | 表头配置主键。不传按 field 或 type 生成。同一字段出现两列,或字段以后会改名时必须指定,指定后不要再改 |
| type | String | '' | vxe 内置列,如 seq |
| title | String | '' | 列标题 |
| width | String / Number | null | 列宽 |
| min-width | String / Number | null | 最小列宽。不传时:有 width 用 width,否则按标题估算(中文 15px、英文 10px,再加 40px) |
| fixed | String | '' | '' / left / right |
| align | String | 'left' | left / center / right |
| sortable | Boolean | false | 可排序 |
| show-overflow | Boolean | true | 超出省略 |
| resizable | Boolean | true | 可拖列宽 |
| tree-node | Boolean | false | 树节点列,显示展开图标 |
| formatter | Function | null | ({ row, column, $index }) => 显示值。优先级低于插槽 |
| editable | Boolean | false | 点击单元格文本编辑 |
| edit-render | Object | null | vxe 编辑器,如 { name: 'input' }。优先于 editable |
插槽:
| 插槽 | 说明 |
|---|---|
| 默认插槽 | 单元格。需要行数据时用作用域插槽,参数来自 vxe-table,常用 row、seq、column |
| edit | 编辑态内容,作用域同上。有此插槽时该列可编辑 |
子组件 StandardFooterLeft
底部栏左侧文本。出现后底部栏自动显示,并占用「数据更新时间」的位置。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| text | String | '' | 左侧文字 |
无插槽。自定义结构用表格的 footer-left 插槽,并打开 show-footer。
子组件 StandardFooterRight
底部栏右侧分页。出现后底部栏自动显示。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| current-page | Number | 1 | 当前页,由页面维护 |
| page-size | Number | 20 | 每页条数,由页面维护 |
| page-sizes | Array | [10, 20, 50, 100, 200, 500] | 每页条数选项 |
| total | Number | 0 | 总条数 |
| layout | String | 'sizes, prev, pager, next, total' | 同 el-pagination |
事件:@page-change,参数 { currentPage, pageSize, type }。type 为 page(翻页)或 size(改每页条数,此时 currentPage 为 1)。无插槽。
子组件 StandardFooterEmpty
没有左右底部内容时,用来留出与底部栏相同的 10px 上间距。左右底部子组件有其一则不占位。无属性、无插槽。
<standard-table
ref="mainTable"
table-code="main"
:table-data="tableData"
:table-operation="tableOperation"
:loading="loading"
:show-update-time="false"
>
<standard-toolbar-left>
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAdd" />
</standard-toolbar-left>
<standard-toolbar-right>
<standard-toolbar-query v-model="keyword" query-method="onQuery" :loading="loading" />
</standard-toolbar-right>
<standard-footer-left :text="footerText" />
<standard-footer-right
:current-page="pageParams.currentPage"
:page-size="pageParams.pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="pageParams.totalResult"
@page-change="onPageChange"
/>
<standard-column type="seq" title="序号" :width="60" :min-width="60" fixed="left" />
<standard-column field="CODE" title="编码" :min-width="120" sortable />
<standard-column field="STATUS" title="状态" :width="100" :min-width="100" align="center">
<template #default="{ row }"><!-- 状态标签 --></template>
</standard-column>
</standard-table>
树形模式:
<standard-table
:table-data="tableData"
:tree-config="treeConfig"
:row-config="rowConfig"
@toggle-tree-expand="onToggleTreeExpand"
>
<standard-column tree-node field="NAME" title="名称" :min-width="220" fixed="left" />
</standard-table>
treeConfig: { transform: true, rowField: 'id', parentField: 'parentId', trigger: 'row', showIcon: true, indent: 20 }
rowConfig: { keyField: 'id' }
StandardTabs / StandardTabPane 标准页签
双标签。头部和内容区是同一张卡片。type、tab-position、stretch 以及 @tab-click、@edit 等透传 el-tabs。
StandardTabs
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| value | String / Number | '' | v-model,当前 pane 的 name |
| lazy | Boolean | false | 懒加载,作用于全部 pane。某个 pane 自己的 lazy 也会生效 |
插槽:默认插槽,放 <standard-tab-pane>。
StandardTabPane
继承 Element UI 的 TabPane。常用属性:label、name、closable、disabled、lazy。插槽:默认插槽,pane 内容。
全局注册名是 StandardTabPane,不会覆盖页面里的 <el-tab-pane>。
<standard-tabs v-model="activeTab" lazy @tab-click="onTabClick">
<standard-tab-pane label="明细" name="detail">
<standard-table :table-data="detailData" />
</standard-tab-pane>
<standard-tab-pane label="记录" name="record" />
</standard-tabs>
StandardTree 标准树
单标签。上为搜索,中为树,下为「全部展开 / 全部收起」。默认手风琴、高亮当前节点、点击节点展开。自带卡片外观。
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| tree-data | Array | [] | v-model,嵌套数据 |
| tree-props | Object | { label: 'label', children: 'children' } | 字段映射 |
| node-key | String | 'id' | 节点唯一键 |
| default-expanded-keys | Array | [] | 默认展开的 key |
| search-placeholder | String | '请输入节点名称搜索' | 搜索框占位 |
| transparent | Boolean | false | 去掉自身卡片并占满父级。放进半区时使用 |
事件:@node-click、@node-expand、@node-collapse。参数与 el-tree 相同:(data, node, tree)。
对外方法(ref):setCurrentKey(key) 设置或取消选中;filter(keyword) 按名称过滤。
无插槽。节点图标和文字由组件内部渲染。
<standard-tree
ref="tree"
v-model="treeData"
node-key="id"
:default-expanded-keys="[1]"
transparent
@node-click="onNodeClick"
/>
treeData: [
{ id: 1, label: '总部', children: [
{ id: 11, label: '技术部' },
{ id: 12, label: '财务部' }
]},
{ id: 2, label: '分公司' }
]
页面骨架
下面五种对应 Web 前端样板里的页面,只保留组件嵌套。样板目录:listPage、multiListPage、linkPage、treeLinkPage、toolbarQueryPage。
标准列表页(listPage)
筛选栏 + 表格(工具栏、底栏、列)+ 详情弹窗里的表格。
<standard-page :client="isClient">
<standard-filterbar v-model="searchBar" show-export reset-trigger-search :loading="loading"
@search="onSearch" @export="onExport" />
<standard-table ref="mainTable" :table-data="tableData" :table-operation="tableOperation"
:loading="loading" :show-update-time="false">
<standard-toolbar-left>
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAdd" />
</standard-toolbar-left>
<standard-toolbar-right />
<standard-footer-left :text="footerText" />
<standard-footer-right :current-page="pageParams.currentPage" :page-size="pageParams.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="pageParams.totalResult"
@page-change="onPageChange" />
<standard-column type="seq" title="序号" fixed="left" />
<standard-column field="CODE" title="编码" :min-width="120" sortable />
</standard-table>
<el-dialog :visible.sync="showDetail" :title="detailTitle" width="900px">
<standard-table :table-data="detailData" :loading="detailLoading" :show-update-time="false"
style="height: 420px">
<standard-toolbar-right>
<standard-button type="primary" label="导出" @click="onDetailExport" />
</standard-toolbar-right>
<standard-column field="NAME" title="项目名称" :min-width="150" />
</standard-table>
</el-dialog>
</standard-page>
多层级树表格页(multiListPage)
筛选栏(可含插槽条件)+ 树表 + 弹窗。弹窗里用容器并排表单和表格。
<standard-page :client="isClient">
<standard-filterbar v-model="searchBar" reset-trigger-search :loading="loading"
@search="onSearch" @reset="onResetExtra">
<standard-filterbar-item label="车间">
<el-select v-model="extra.workshop" size="mini" clearable />
</standard-filterbar-item>
</standard-filterbar>
<standard-table ref="xTable" :table-data="tableData" :table-operation="tableOperation"
:loading="loading" :show-update-time="false"
:tree-config="treeConfig" :row-config="rowConfig"
@toggle-tree-expand="onToggleTreeExpand">
<standard-toolbar-left>
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAdd" />
</standard-toolbar-left>
<standard-toolbar-right>
<standard-button :label="expanded ? '收起' : '展开'" @click="toggleExpandAll" />
</standard-toolbar-right>
<standard-footer-empty />
<standard-column tree-node field="NAME" title="名称" :min-width="220" fixed="left" />
<standard-column field="CODE" title="编码" :width="110" :min-width="110" align="center" />
</standard-table>
<standard-dialog v-model="showEdit" :title="dialogTitle" :confirm-loading="saving"
@confirm="submit" @close="close">
<standard-container direction="row" width="400px">
<standard-container>
<standard-form ref="editForm" :model="form" :rules="formRules">
<standard-form-item label="名称" prop="NAME" :span="12">
<standard-input v-model="form.NAME" />
</standard-form-item>
</standard-form>
</standard-container>
<standard-container>
<standard-table :table-data="dialogTableData">
<standard-toolbar-left>
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAddLine" />
</standard-toolbar-left>
<standard-footer-empty />
<standard-column field="CODE" title="编码" />
</standard-table>
</standard-container>
</standard-container>
</standard-dialog>
</standard-page>
左右联动页(linkPage)
左右半区透明,中间百分比分割条。左侧筛选 + 表格;右侧筛选 + 页签,每个页签一张表。
<standard-page :client="isClient" vertical>
<standard-half-area v-show="leftVisible" transparent :style="leftPanelStyle">
<standard-filterbar v-model="leftSearchBar" show-advanced-query reset-trigger-search
:loading="leftLoading" @search="onLeftSearch" />
<standard-table ref="leftTable" :table-data="leftTableData" :loading="leftLoading"
:show-update-time="false" @current-change="onLeftCurrentChange">
<standard-toolbar-left :buttons="leftToolbarButtons" />
<standard-footer-right :current-page="leftPage.currentPage" :page-size="leftPage.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="leftPage.totalResult"
@page-change="onLeftPageChange" />
<standard-column type="seq" title="序号" :width="60" :min-width="60" fixed="left" />
<standard-column field="NAME" title="名称" :min-width="180" sortable />
</standard-table>
</standard-half-area>
<standard-splitter v-show="leftVisible && rightVisible" v-model="leftPercent" unit="percent"
@drag-end="recalculateAll" />
<standard-half-area v-show="rightVisible" right transparent>
<standard-filterbar :key="activeTab" v-model="rightSearchBar" show-advanced-query
reset-trigger-search :loading="rightLoading" @search="onRightSearch" />
<standard-tabs v-model="activeTab" lazy @tab-click="onTabClick">
<standard-tab-pane label="明细" name="detail">
<standard-table ref="detailTable" :table-data="detailData" :loading="rightLoading"
:show-update-time="false">
<standard-toolbar-left :buttons="detailToolbarButtons" />
<standard-footer-right :current-page="rightPage.currentPage" :page-size="rightPage.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="rightPage.totalResult"
@page-change="onRightPageChange" />
<standard-column type="seq" title="序号" :width="60" :min-width="60" fixed="left" />
</standard-table>
</standard-tab-pane>
<standard-tab-pane label="记录" name="record" />
<standard-tab-pane label="日志" name="log" />
</standard-tabs>
</standard-half-area>
</standard-page>
树 + 列表联动页(treeLinkPage)
左半区放树,分割条用像素宽度,右半区是带关键字查询的表格,弹窗里放表单。
<standard-page :client="isClient" vertical>
<standard-half-area v-show="leftVisible" left :style="{ width: leftWidth + 'px' }">
<standard-tree ref="tree" v-model="treeData" node-key="id" :default-expanded-keys="[1]"
transparent @node-click="onNodeClick" />
</standard-half-area>
<standard-splitter v-show="leftVisible" v-model="leftWidth" :min-width="200" :max-ratio="0.6" />
<standard-half-area right>
<standard-table ref="xTable" :table-data="tableData" :table-operation="tableOperation"
:loading="loading" show-footer :show-update-time="false">
<standard-toolbar-left>
<standard-button :label="leftVisible ? '收起' : '展开'" @click="toggleLeft" />
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAdd" />
<standard-button icon="el-icon-upload" label="导出" @click="onExport" />
</standard-toolbar-left>
<standard-toolbar-right>
<standard-input v-model="keyword" placeholder="请输入关键字" @enter="onSearch" />
<standard-button type="primary" icon="el-icon-search" label="查询" :loading="loading" @click="onSearch" />
</standard-toolbar-right>
<template #footer-left><!-- 当前节点 --></template>
<standard-footer-right :current-page="pageParams.currentPage" :page-size="pageParams.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="pageParams.totalResult"
@page-change="onPageChange" />
<standard-column type="seq" title="序号" :width="60" :min-width="60" fixed="left" />
<standard-column field="CODE" title="编码" :min-width="140" sortable />
</standard-table>
</standard-half-area>
<standard-dialog v-model="showEdit" :title="dialogTitle" :confirm-loading="saving"
@confirm="submit" @close="close">
<standard-form ref="editForm" :model="form" :rules="formRules" width="400px">
<standard-form-item label="编码" prop="CODE" :span="12">
<standard-input v-model="form.CODE" />
</standard-form-item>
</standard-form>
</standard-dialog>
</standard-page>
树表联动页若要显示 #footer-left,表格需要 show-footer。只放 <standard-footer-right> 时底部栏也会出现,此时左侧自定义内容仍要 show-footer。
工具栏查询列表页(toolbarQueryPage)
没有独立筛选栏。关键字查询放在表格右侧工具栏。
<standard-page :client="isClient">
<standard-table ref="mainTable" :table-data="tableData" :loading="loading" :show-update-time="false">
<standard-toolbar-left>
<standard-button type="primary" icon="el-icon-plus" label="新增" @click="onAdd" />
<standard-button icon="el-icon-refresh" label="刷新" @click="onRefresh" />
</standard-toolbar-left>
<standard-toolbar-right>
<standard-toolbar-query v-model="keyword" placeholder="请输入编码/名称" query-method="onQuery"
show-export export-method="onExport" :loading="loading" />
</standard-toolbar-right>
<standard-footer-right :current-page="pageParams.currentPage" :page-size="pageParams.pageSize"
:page-sizes="[10, 20, 50, 100]" :total="pageParams.totalResult"
@page-change="onPageChange" />
<standard-column type="seq" title="序号" :width="60" :min-width="60" fixed="left" />
<standard-column field="CODE" title="编码" :min-width="140" sortable />
<standard-column field="NAME" title="名称" :min-width="180" sortable />
</standard-table>
</standard-page>
开发与构建
npm install
npm run build
使用 @vue/cli-service 的 lib 模式,产物在 dist/:standard-ui.common.js(CommonJS)和 standard-ui.umd.min.js(UMD)。样式打进 JS。vue 由构建工具 external。src/index.js 会 import vxe-table,因此 element-ui、vxe-table 及其运行时依赖 @vxe-ui/core 的部分代码会打进 dist。
vxe-table 3.24 说明
本包 peerDependencies 为 vxe-table ^3.24.0。使用方注册方式不变:import VXETable from 'vxe-table'、引入 vxe-table/lib/style.css、Vue.use(VXETable)。
- vxe-table 3.24 运行时依赖
@vxe-ui/core,但其 package.json 未声明该依赖。本包已在 dependencies 中声明@vxe-ui/core ^3.4.24。使用方若单独使用 vxe-table、不依赖本包,需要自己安装@vxe-ui/core@^3.4.24。 - 从 3.6 / 3.8 升到 3.24 时,使用方自己写的 vxe-table 需要注意:纵向/横向虚拟滚动默认关闭;
tree-config的line/hasChild/children更名为showLine/hasChildField/childrenField(旧名仍兼容);图标fixed/fixed-fill更名为fixed-left/fixed-left-fill。 - 本库
install时执行的VXETable.setup({ zIndex: 5000 })只作用于产物内的副本。使用方自己的 vxe-table 要在main.js里另行 setup,或给<standard-table>传z-index。 - vxe-table 3.24 是 Vue 2 线的最后版本,Vue 2.6 可直接使用。
发布
npm run build
npm login
npm publish
files 只有 dist,发布内容是构建产物和 README。版本更新用 npm version patch|minor|major 后再 npm publish。