Browse Source

feat(components): 接入vextable组件

pull/768/head
cKey 3 years ago
parent
commit
87a72b37a0
  1. 3
      apps/vue/build/vite/plugin/styleImport.ts
  2. 5
      apps/vue/package.json
  3. 12
      apps/vue/src/components/VxeTable/index.ts
  4. 108
      apps/vue/src/components/VxeTable/src/VxeBasicTable.tsx
  5. 59
      apps/vue/src/components/VxeTable/src/componentMap.ts
  6. 22
      apps/vue/src/components/VxeTable/src/componentType.ts
  7. 20
      apps/vue/src/components/VxeTable/src/components/AApiSelect.tsx
  8. 16
      apps/vue/src/components/VxeTable/src/components/AAutoComplete.tsx
  9. 120
      apps/vue/src/components/VxeTable/src/components/AButton.tsx
  10. 59
      apps/vue/src/components/VxeTable/src/components/AButtonGroup.tsx
  11. 42
      apps/vue/src/components/VxeTable/src/components/ACascader.tsx
  12. 5
      apps/vue/src/components/VxeTable/src/components/ACheckboxGroup.tsx
  13. 33
      apps/vue/src/components/VxeTable/src/components/ADatePicker.tsx
  14. 27
      apps/vue/src/components/VxeTable/src/components/AEmpty.tsx
  15. 16
      apps/vue/src/components/VxeTable/src/components/AInput.tsx
  16. 16
      apps/vue/src/components/VxeTable/src/components/AInputNumber.tsx
  17. 17
      apps/vue/src/components/VxeTable/src/components/AInputSearch.tsx
  18. 18
      apps/vue/src/components/VxeTable/src/components/AMonthPicker.tsx
  19. 5
      apps/vue/src/components/VxeTable/src/components/ARadioGroup.tsx
  20. 30
      apps/vue/src/components/VxeTable/src/components/ARangePicker.tsx
  21. 15
      apps/vue/src/components/VxeTable/src/components/ARate.tsx
  22. 271
      apps/vue/src/components/VxeTable/src/components/ASelect.tsx
  23. 53
      apps/vue/src/components/VxeTable/src/components/ASwitch.tsx
  24. 18
      apps/vue/src/components/VxeTable/src/components/ATimePicker.tsx
  25. 35
      apps/vue/src/components/VxeTable/src/components/ATreeSelect.tsx
  26. 18
      apps/vue/src/components/VxeTable/src/components/AWeekPicker.tsx
  27. 18
      apps/vue/src/components/VxeTable/src/components/AYearPicker.tsx
  28. 427
      apps/vue/src/components/VxeTable/src/components/common.tsx
  29. 112
      apps/vue/src/components/VxeTable/src/components/index.tsx
  30. 4
      apps/vue/src/components/VxeTable/src/const.ts
  31. 8
      apps/vue/src/components/VxeTable/src/css/common.scss
  32. 105
      apps/vue/src/components/VxeTable/src/css/component.scss
  33. 6
      apps/vue/src/components/VxeTable/src/css/index.scss
  34. 24
      apps/vue/src/components/VxeTable/src/css/scrollbar.scss
  35. 30
      apps/vue/src/components/VxeTable/src/css/toolbar.scss
  36. 6
      apps/vue/src/components/VxeTable/src/css/variable.scss
  37. 17
      apps/vue/src/components/VxeTable/src/emits.ts
  38. 19
      apps/vue/src/components/VxeTable/src/helper.ts
  39. 131
      apps/vue/src/components/VxeTable/src/methods.ts
  40. 52
      apps/vue/src/components/VxeTable/src/props.ts
  41. 4
      apps/vue/src/components/VxeTable/src/setting.ts
  42. 7
      apps/vue/src/components/VxeTable/src/types.ts
  43. 3
      apps/vue/src/components/registerGlobComp.ts
  44. 1
      apps/vue/src/main.ts
  45. 46
      apps/vue/src/settings/componentSetting.ts

3
apps/vue/build/vite/plugin/styleImport.ts

@ -2,7 +2,7 @@
* Introduces component library styles on demand.
* https://github.com/anncwb/vite-plugin-style-import
*/
import { createStyleImportPlugin } from 'vite-plugin-style-import';
import { createStyleImportPlugin, VxeTableResolve } from 'vite-plugin-style-import';
export function configStyleImportPlugin(_isBuild: boolean) {
// if (!isBuild) {
@ -77,6 +77,7 @@ export function configStyleImportPlugin(_isBuild: boolean) {
},
},
],
resolves: [VxeTableResolve()],
});
return styleImportPlugin;
}

5
apps/vue/package.json

@ -53,6 +53,7 @@
"czg": "^1.3.9",
"dayjs": "^1.11.1",
"echarts": "^5.3.2",
"exceljs": "^4.3.0",
"intro.js": "^5.1.0",
"lodash-es": "^4.17.21",
"mockjs": "^1.1.0",
@ -76,6 +77,9 @@
"vue-router": "^4.0.14",
"vue-types": "^4.1.1",
"vue3-colorpicker": "^2.0.4",
"vxe-table": "^4.3.9",
"vxe-table-plugin-export-xlsx": "^3.0.4",
"xe-utils": "^3.5.7",
"xlsx": "^0.18.5"
},
"devDependencies": {
@ -127,6 +131,7 @@
"rimraf": "^3.0.2",
"rollup": "^2.70.2",
"rollup-plugin-visualizer": "^5.6.0",
"sass": "^1.57.1",
"stylelint": "^14.7.1",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-recommended": "^7.0.0",

12
apps/vue/src/components/VxeTable/index.ts

@ -0,0 +1,12 @@
import { withInstall } from '/@/utils';
import vxeBasicTable from './src/VxeBasicTable';
import { VXETable } from 'vxe-table';
import VXETablePluginAntd from './src/components';
import VXETablePluginExportXLSX from 'vxe-table-plugin-export-xlsx';
import './src/setting';
export const VxeBasicTable = withInstall(vxeBasicTable);
export * from 'vxe-table';
export * from './src/types';
VXETable.use(VXETablePluginAntd).use(VXETablePluginExportXLSX);

108
apps/vue/src/components/VxeTable/src/VxeBasicTable.tsx

@ -0,0 +1,108 @@
import { defineComponent } from 'vue';
import { computed, ref } from 'vue';
import { BasicTableProps } from './types';
import { omit } from 'lodash';
import { basicProps } from './props';
import { ignorePropKeys } from './const';
import { basicEmits } from './emits';
import XEUtils from 'xe-utils';
import type { VxeGridInstance, VxeGridEventProps, GridMethods, TableMethods } from 'vxe-table';
import { Grid as VxeGrid } from 'vxe-table';
import { extendSlots } from '/@/utils/helper/tsxHelper';
import { gridComponentMethodKeys } from './methods';
export default defineComponent({
name: 'VxeBasicTable',
props: basicProps,
emits: basicEmits,
setup(props, { emit, attrs }) {
const tableElRef = ref<VxeGridInstance>();
const emitEvents: VxeGridEventProps = {};
const extendTableMethods = (methodKeys) => {
const funcs: any = {};
methodKeys.forEach((name) => {
funcs[name] = (...args: any[]) => {
const $vxegrid: any = tableElRef.value;
if ($vxegrid && $vxegrid[name]) {
return $vxegrid[name](...args);
}
};
});
return funcs;
};
const gridExtendTableMethods = extendTableMethods(gridComponentMethodKeys) as GridMethods &
TableMethods;
basicEmits.forEach((name) => {
const type = XEUtils.camelCase(`on-${name}`) as keyof VxeGridEventProps;
emitEvents[type] = (...args: any[]) => emit(name, ...args);
});
/**
* @description:
* 1.
*/
const getBindValues = computed<BasicTableProps>(() => {
const propsData: BasicTableProps = {
...attrs,
...props,
};
return propsData;
});
/**
* @description: Table
*/
const getBindGridValues = computed(() => {
const omitProps = omit(getBindValues.value, ignorePropKeys);
return {
...omitProps,
...getBindGridEvent,
};
});
/**
* @description: class
*/
const getWrapperClass = computed(() => {
return [attrs.class];
});
/**
* @description: Vxe-table
*/
const getBindGridEvent: VxeGridEventProps = {
...emitEvents,
};
return {
getWrapperClass,
getBindGridValues,
tableElRef,
...gridExtendTableMethods,
};
},
render() {
const { tableClass, tableStyle } = this.$props;
return (
<div class={`h-full flex flex-col bg-white ${this.getWrapperClass}`}>
<VxeGrid
ref="tableElRef"
class={`vxe-grid_scrollbar px-6 py-4 ${tableClass}`}
style={tableStyle}
{...this.getBindGridValues}
>
{extendSlots(this.$slots)}
</VxeGrid>
</div>
);
},
});

59
apps/vue/src/components/VxeTable/src/componentMap.ts

@ -0,0 +1,59 @@
import type { Component } from 'vue';
import type { ComponentType } from './componentType';
import { ApiSelect, ApiTreeSelect } from '/@/components/Form';
import {
Input,
Select,
Radio,
Checkbox,
AutoComplete,
Cascader,
DatePicker,
InputNumber,
Switch,
TimePicker,
TreeSelect,
Rate,
Button,
Empty,
} from 'ant-design-vue';
const componentMap = new Map<ComponentType, Component>();
componentMap.set('AButton', Button);
componentMap.set('AInput', Input);
componentMap.set('AInputSearch', Input.Search);
componentMap.set('AInputNumber', InputNumber);
componentMap.set('AAutoComplete', AutoComplete);
componentMap.set('ASelect', Select);
componentMap.set('ATreeSelect', TreeSelect);
componentMap.set('ASwitch', Switch);
componentMap.set('ARadioGroup', Radio.Group);
componentMap.set('ACheckboxGroup', Checkbox.Group);
componentMap.set('ACascader', Cascader);
componentMap.set('ARate', Rate);
componentMap.set('ADatePicker', DatePicker);
componentMap.set('AMonthPicker', DatePicker.MonthPicker);
componentMap.set('ARangePicker', DatePicker.RangePicker);
componentMap.set('AWeekPicker', DatePicker.WeekPicker);
componentMap.set('AYearPicker', DatePicker.YearPicker);
componentMap.set('ATimePicker', TimePicker);
componentMap.set('AApiSelect', ApiSelect);
componentMap.set('AApiTreeSelect', ApiTreeSelect);
componentMap.set('AEmpty', Empty);
export function add(compName: ComponentType, component: Component) {
componentMap.set(compName, component);
}
export function del(compName: ComponentType) {
componentMap.delete(compName);
}
export { componentMap };

22
apps/vue/src/components/VxeTable/src/componentType.ts

@ -0,0 +1,22 @@
export type ComponentType =
| 'AInput'
| 'AInputNumber'
| 'ASelect'
| 'AApiSelect'
| 'ATreeSelect'
| 'AApiTreeSelect'
| 'ARadioGroup'
| 'ACheckboxGroup'
| 'AAutoComplete'
| 'ACascader'
| 'ADatePicker'
| 'AMonthPicker'
| 'ARangePicker'
| 'AWeekPicker'
| 'ATimePicker'
| 'AYearPicker'
| 'ASwitch'
| 'ARate'
| 'AInputSearch'
| 'AButton'
| 'AEmpty';

20
apps/vue/src/components/VxeTable/src/components/AApiSelect.tsx

@ -0,0 +1,20 @@
import XEUtils from 'xe-utils';
import { createDefaultRender, createEditRender, createFormItemRender } from './common';
export default {
renderDefault: createDefaultRender({}, (_, params) => {
return {
params: XEUtils.get(params, 'row'),
};
}),
renderEdit: createEditRender({}, (_, params) => {
return {
params: XEUtils.get(params, 'row'),
};
}),
renderItemContent: createFormItemRender({}, (_, params) => {
return {
params: XEUtils.get(params, 'row'),
};
}),
};

16
apps/vue/src/components/VxeTable/src/components/AAutoComplete.tsx

@ -0,0 +1,16 @@
import {
createEditRender,
createDefaultRender,
createFilterRender,
createDefaultFilterRender,
createFormItemRender,
} from './common';
export default {
autofocus: 'input.ant-input',
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter: createFilterRender(),
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
};

120
apps/vue/src/components/VxeTable/src/components/AButton.tsx

@ -0,0 +1,120 @@
import { h } from 'vue';
import {
FormItemContentRenderParams,
FormItemRenderOptions,
VxeGlobalRendererHandles,
} from 'vxe-table';
import XEUtils from 'xe-utils';
import { cellText, createEvents, createProps, getComponent } from './common';
const COMPONENT_NAME = 'AButton';
export function createEditRender() {
return function (
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
params: VxeGlobalRendererHandles.RenderEditParams,
) {
const { attrs } = renderOpts;
const Component = getComponent(COMPONENT_NAME);
return [
h(Component, {
...attrs,
...createProps(renderOpts, null),
...createEvents(renderOpts, params),
}),
];
};
}
export function createDefaultRender() {
return function (
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
params: VxeGlobalRendererHandles.RenderEditParams,
) {
const { attrs } = renderOpts;
const Component = getComponent(COMPONENT_NAME);
return [
h(
Component,
{
...attrs,
...createProps(renderOpts, null),
...createEvents(renderOpts, params),
},
cellText(renderOpts.content),
),
];
};
}
export function createFormItemRender() {
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
const { attrs, content } = renderOpts;
const { property, $form, data } = params;
const props = createProps(renderOpts, null);
const Component = getComponent(COMPONENT_NAME);
return [
h(
Component,
{
...attrs,
...props,
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
XEUtils.set(data, property, value);
},
() => {
// 处理 change 事件相关逻辑
$form.updateStatus({
...params,
field: property,
});
},
),
},
{
default: () => cellText(content || props.content),
},
),
];
};
}
function createToolbarButtonRender() {
return function (
renderOpts: VxeGlobalRendererHandles.RenderToolOptions,
params: VxeGlobalRendererHandles.RenderButtonParams,
) {
const { attrs } = renderOpts;
const { button } = params;
const props = createProps(renderOpts, null);
const Component = getComponent(COMPONENT_NAME);
return [
h(
Component,
{
...attrs,
...props,
...createEvents(renderOpts, params),
},
{
default: () => cellText(button?.content || props.content),
},
),
];
};
}
export default {
renderEdit: createEditRender(),
renderDefault: createDefaultRender(),
renderItemContent: createFormItemRender(),
renderToolbarButton: createToolbarButtonRender(),
};

59
apps/vue/src/components/VxeTable/src/components/AButtonGroup.tsx

@ -0,0 +1,59 @@
import {
FormItemContentRenderParams,
FormItemRenderOptions,
VxeGlobalRendererHandles,
} from 'vxe-table';
import { createDefaultRender, createEditRender, createFormItemRender } from './AButton';
function createEditButtonRender() {
return function (
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
params: VxeGlobalRendererHandles.RenderEditParams,
) {
const buttonEditRender = createEditRender();
const { children } = renderOpts;
if (children) {
return children.map(
(childRenderOpts: VxeGlobalRendererHandles.RenderEditOptions) =>
buttonEditRender(childRenderOpts, params)[0],
);
}
return [];
};
}
function createDefaultButtonRender() {
return function (
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
params: VxeGlobalRendererHandles.RenderDefaultParams,
) {
const buttonDefaultRender = createDefaultRender();
const { children } = renderOpts;
if (children) {
return children.map(
(childRenderOpts: VxeGlobalRendererHandles.RenderDefaultOptions) =>
buttonDefaultRender(childRenderOpts, params)[0],
);
}
return [];
};
}
function createButtonItemRender() {
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
const buttonItemRender = createFormItemRender();
const { children } = renderOpts;
if (children) {
return children.map(
(childRenderOpts: FormItemRenderOptions) => buttonItemRender(childRenderOpts, params)[0],
);
}
return [];
};
}
export default {
renderEdit: createEditButtonRender(),
renderDefault: createDefaultButtonRender(),
renderItemContent: createButtonItemRender(),
};

42
apps/vue/src/components/VxeTable/src/components/ACascader.tsx

@ -0,0 +1,42 @@
import { VxeGlobalRendererHandles } from 'vxe-table';
import XEUtils from 'xe-utils';
import {
createEditRender,
createCellRender,
createFormItemRender,
createExportMethod,
} from './common';
function matchCascaderData(index: number, list: any[], values: any[], labels: any[]) {
const val = values[index];
if (list && values.length > index) {
XEUtils.each(list, (item) => {
if (item.value === val) {
labels.push(item.label);
matchCascaderData(++index, item.children, values, labels);
}
});
}
}
function getCascaderCellValue(
renderOpts: VxeGlobalRendererHandles.RenderOptions,
params: VxeGlobalRendererHandles.RenderCellParams,
) {
const { props = {} } = renderOpts;
const { row, column } = params;
const cellValue = XEUtils.get(row, column.field as string);
const values = cellValue || [];
const labels: Array<any> = [];
matchCascaderData(0, props.options, values, labels);
return (
props.showAllLevels === false ? labels.slice(labels.length - 1, labels.length) : labels
).join(` ${props.separator || '/'} `);
}
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getCascaderCellValue),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getCascaderCellValue),
};

5
apps/vue/src/components/VxeTable/src/components/ACheckboxGroup.tsx

@ -0,0 +1,5 @@
import { createFormItemRender } from './common';
export default {
renderItemContent: createFormItemRender(),
};

33
apps/vue/src/components/VxeTable/src/components/ADatePicker.tsx

@ -0,0 +1,33 @@
import { VxeGlobalRendererHandles } from 'vxe-table';
import XEUtils from 'xe-utils';
import {
createCellRender,
createEditRender,
createExportMethod,
createFormItemRender,
} from './common';
export function getDatePickerCellValue(
renderOpts: VxeGlobalRendererHandles.RenderOptions,
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
defaultFormat: string,
) {
const { props = {} } = renderOpts;
const { row, column } = params;
let cellValue = XEUtils.get(row, column.field as string);
if (cellValue) {
cellValue = cellValue.format(props.format || defaultFormat);
}
return cellValue;
}
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getDatePickerCellValue, () => {
return ['YYYY-MM-DD'];
}),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getDatePickerCellValue, () => {
return ['YYYY-MM-DD'];
}),
};

27
apps/vue/src/components/VxeTable/src/components/AEmpty.tsx

@ -0,0 +1,27 @@
import { h } from 'vue';
import { VxeGlobalRendererHandles } from 'vxe-table';
import { getComponent } from './common';
function createEmptyRender() {
return function (renderOpts: VxeGlobalRendererHandles.RenderEmptyOptions) {
const { name, attrs, props } = renderOpts;
const Component = getComponent(name);
return [
h(
'div',
{
class: 'flex items-center justify-center',
},
h(Component, {
...attrs,
...props,
}),
),
];
};
}
export default {
renderEmpty: createEmptyRender(),
};

16
apps/vue/src/components/VxeTable/src/components/AInput.tsx

@ -0,0 +1,16 @@
import {
createEditRender,
createDefaultRender,
createFilterRender,
createDefaultFilterRender,
createFormItemRender,
} from './common';
export default {
autofocus: 'input.ant-input',
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter: createFilterRender(),
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
};

16
apps/vue/src/components/VxeTable/src/components/AInputNumber.tsx

@ -0,0 +1,16 @@
import {
createEditRender,
createFilterRender,
createFormItemRender,
createDefaultFilterRender,
createDefaultRender,
} from './common';
export default {
autofocus: 'input.ant-input-number-input',
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter: createFilterRender(),
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
};

17
apps/vue/src/components/VxeTable/src/components/AInputSearch.tsx

@ -0,0 +1,17 @@
import {
createEditRender,
createDefaultRender,
createFilterRender,
createDefaultFilterRender,
createFormItemRender,
createToolbarToolRender,
} from './common';
export default {
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter: createFilterRender(),
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
renderToolbarTool: createToolbarToolRender(),
};

18
apps/vue/src/components/VxeTable/src/components/AMonthPicker.tsx

@ -0,0 +1,18 @@
import { getDatePickerCellValue } from './ADatePicker';
import {
createCellRender,
createEditRender,
createExportMethod,
createFormItemRender,
} from './common';
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getDatePickerCellValue, () => {
return ['YYYY-MM'];
}),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getDatePickerCellValue, () => {
return ['YYYY-MM'];
}),
};

5
apps/vue/src/components/VxeTable/src/components/ARadioGroup.tsx

@ -0,0 +1,5 @@
import { createFormItemRender } from './common';
export default {
renderItemContent: createFormItemRender(),
};

30
apps/vue/src/components/VxeTable/src/components/ARangePicker.tsx

@ -0,0 +1,30 @@
import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table';
import XEUtils from 'xe-utils';
import {
createCellRender,
createEditRender,
createExportMethod,
createFormItemRender,
} from './common';
function getRangePickerCellValue(
renderOpts: VxeColumnPropTypes.EditRender,
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
) {
const { props = {} } = renderOpts;
const { row, column } = params;
let cellValue = XEUtils.get(row, column.field as string);
if (cellValue) {
cellValue = XEUtils.map(cellValue, (date: any) =>
date.format(props.format || 'YYYY-MM-DD'),
).join(' ~ ');
}
return cellValue;
}
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getRangePickerCellValue),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getRangePickerCellValue),
};

15
apps/vue/src/components/VxeTable/src/components/ARate.tsx

@ -0,0 +1,15 @@
import {
createEditRender,
createDefaultRender,
createFilterRender,
createDefaultFilterRender,
createFormItemRender,
} from './common';
export default {
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter: createFilterRender(),
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
};

271
apps/vue/src/components/VxeTable/src/components/ASelect.tsx

@ -0,0 +1,271 @@
import { ComponentOptions, h, resolveComponent } from 'vue';
import { VxeColumnPropTypes, VxeGlobalRendererHandles } from 'vxe-table';
import XEUtils from 'xe-utils';
import {
cellText,
createCellRender,
createEvents,
createProps,
isEmptyValue,
createExportMethod,
createFormItemRender,
} from './common';
function renderOptions(options: any[], optionProps: VxeGlobalRendererHandles.RenderOptionProps) {
const labelProp = optionProps.label || 'label';
const valueProp = optionProps.value || 'value';
return XEUtils.map(options, (item, oIndex) => {
return h(
resolveComponent('a-select-option') as ComponentOptions,
{
key: oIndex,
value: item[valueProp],
disabled: item.disabled,
},
{
default: () => cellText(item[labelProp]),
},
);
});
}
function createEditRender() {
return function (
renderOpts: VxeColumnPropTypes.EditRender,
params: VxeGlobalRendererHandles.RenderEditParams,
) {
const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
const { row, column, $table } = params;
const { attrs } = renderOpts;
const cellValue = XEUtils.get(row, column.field as string);
const props = createProps(renderOpts, cellValue);
const ons = createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
XEUtils.set(row, column.field as string, value);
},
() => {
// 处理 change 事件相关逻辑
$table.updateStatus(params);
},
);
if (optionGroups) {
const groupOptions = optionGroupProps.options || 'options';
const groupLabel = optionGroupProps.label || 'label';
return [
h(
resolveComponent('a-select') as ComponentOptions,
{
...attrs,
...props,
...ons,
},
{
default: () => {
return XEUtils.map(optionGroups, (group, gIndex) => {
return h(
resolveComponent('a-select-opt-group') as ComponentOptions,
{
key: gIndex,
},
{
label: () => {
return h('span', {}, group[groupLabel]);
},
default: () => renderOptions(group[groupOptions], optionProps),
},
);
});
},
},
),
];
}
return [
h(
resolveComponent('a-select') as ComponentOptions,
{
...props,
...attrs,
...ons,
},
{
default: () => renderOptions(options, optionProps),
},
),
];
};
}
function getSelectCellValue(
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
params: VxeGlobalRendererHandles.RenderCellParams,
) {
const {
options = [],
optionGroups,
props = {},
optionProps = {},
optionGroupProps = {},
} = renderOpts;
const { row, column } = params;
const labelProp = optionProps.label || 'label';
const valueProp = optionProps.value || 'value';
const groupOptions = optionGroupProps.options || 'options';
const cellValue = XEUtils.get(row, column.field as string);
if (!isEmptyValue(cellValue)) {
return XEUtils.map(
props.mode === 'multiple' ? cellValue : [cellValue],
optionGroups
? (value) => {
let selectItem;
for (let index = 0; index < optionGroups.length; index++) {
selectItem = XEUtils.find(
optionGroups[index][groupOptions],
(item) => item[valueProp] === value,
);
if (selectItem) {
break;
}
}
return selectItem ? selectItem[labelProp] : value;
}
: (value) => {
const selectItem = XEUtils.find(options, (item) => item[valueProp] === value);
return selectItem ? selectItem[labelProp] : value;
},
).join(', ');
}
return '';
}
function createFilterRender() {
return function (
renderOpts: VxeColumnPropTypes.FilterRender,
params: VxeGlobalRendererHandles.RenderFilterParams,
) {
const { options = [], optionGroups, optionProps = {}, optionGroupProps = {} } = renderOpts;
const groupOptions = optionGroupProps.options || 'options';
const groupLabel = optionGroupProps.label || 'label';
const { column } = params;
const { attrs } = renderOpts;
return [
h(
'div',
{
class: 'vxe-table--filter-antd-wrapper',
},
optionGroups
? column.filters.map((option, oIndex) => {
const optionValue = option.data;
const props = createProps(renderOpts, optionValue);
return h(
resolveComponent('a-select') as ComponentOptions,
{
key: oIndex,
...attrs,
...props,
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
option.data = value;
},
() => {
// 处理 change 事件相关逻辑
const { $panel } = params;
$panel.changeOption(
null,
props.mode === 'multiple'
? option.data && option.data.length > 0
: !XEUtils.eqNull(option.data),
option,
);
},
),
},
{
default: () => {
return XEUtils.map(optionGroups, (group, gIndex) => {
return h(
resolveComponent('a-select-opt-group') as ComponentOptions,
{
key: gIndex,
},
{
label: () => {
return h('span', {}, group[groupLabel]);
},
default: () => renderOptions(group[groupOptions], optionProps),
},
);
});
},
},
);
})
: column.filters.map((option, oIndex) => {
const optionValue = option.data;
const props = createProps(renderOpts, optionValue);
return h(
resolveComponent('a-select') as ComponentOptions,
{
key: oIndex,
...attrs,
...props,
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
option.data = value;
},
() => {
// 处理 change 事件相关逻辑
const { $panel } = params;
$panel.changeOption(
null,
props.mode === 'multiple'
? option.data && option.data.length > 0
: !XEUtils.eqNull(option.data),
option,
);
},
),
},
{
default: () => renderOptions(options, optionProps),
},
);
}),
),
];
};
}
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getSelectCellValue),
renderFilter: createFilterRender(),
defaultFilterMethod(params) {
const { option, row, column } = params;
const { data } = option;
const { field, filterRender: renderOpts } = column;
const { props = {} } = renderOpts;
const cellValue = XEUtils.get(row, field);
if (props.mode === 'multiple') {
if (XEUtils.isArray(cellValue)) {
return XEUtils.includeArrays(cellValue, data);
}
return data.indexOf(cellValue) > -1;
}
return cellValue == data;
},
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getSelectCellValue),
};

53
apps/vue/src/components/VxeTable/src/components/ASwitch.tsx

@ -0,0 +1,53 @@
import { h } from 'vue';
import XEUtils from 'xe-utils';
import {
createEditRender,
createDefaultRender,
createProps,
createEvents,
createDefaultFilterRender,
createFormItemRender,
getComponent,
} from './common';
export default {
renderDefault: createDefaultRender(),
renderEdit: createEditRender(),
renderFilter(renderOpts, params) {
const { column } = params;
const { name, attrs } = renderOpts;
const Component = getComponent(name);
return [
h(
'div',
{
class: 'vxe-table--filter-antd-wrapper',
},
column.filters.map((option, oIndex) => {
const optionValue = option.data;
return h(Component, {
key: oIndex,
...attrs,
...createProps(renderOpts, optionValue),
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
option.data = value;
},
() => {
// 处理 change 事件相关逻辑
const { $panel } = params;
$panel.changeOption(null, XEUtils.isBoolean(option.data), option);
},
),
});
}),
),
];
},
defaultFilterMethod: createDefaultFilterRender(),
renderItemContent: createFormItemRender(),
};

18
apps/vue/src/components/VxeTable/src/components/ATimePicker.tsx

@ -0,0 +1,18 @@
import { getDatePickerCellValue } from './ADatePicker';
import {
createEditRender,
createCellRender,
createFormItemRender,
createExportMethod,
} from './common';
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getDatePickerCellValue, () => {
return ['HH:mm:ss'];
}),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getDatePickerCellValue, () => {
return ['HH:mm:ss'];
}),
};

35
apps/vue/src/components/VxeTable/src/components/ATreeSelect.tsx

@ -0,0 +1,35 @@
import { VxeGlobalRendererHandles } from 'vxe-table';
import XEUtils from 'xe-utils';
import {
createEditRender,
createCellRender,
isEmptyValue,
createFormItemRender,
createExportMethod,
} from './common';
function getTreeSelectCellValue(
renderOpts: VxeGlobalRendererHandles.RenderOptions,
params: VxeGlobalRendererHandles.RenderCellParams | VxeGlobalRendererHandles.ExportMethodParams,
) {
const { props = {} } = renderOpts;
const { treeData, treeCheckable } = props;
const { row, column } = params;
const cellValue = XEUtils.get(row, column.field as string);
if (!isEmptyValue(cellValue)) {
return XEUtils.map(treeCheckable ? cellValue : [cellValue], (value) => {
const matchObj = XEUtils.findTree(treeData, (item: any) => item.value === value, {
children: 'children',
});
return matchObj ? matchObj.item.title : value;
}).join(', ');
}
return cellValue;
}
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getTreeSelectCellValue),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getTreeSelectCellValue),
};

18
apps/vue/src/components/VxeTable/src/components/AWeekPicker.tsx

@ -0,0 +1,18 @@
import { getDatePickerCellValue } from './ADatePicker';
import {
createEditRender,
createCellRender,
createFormItemRender,
createExportMethod,
} from './common';
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getDatePickerCellValue, () => {
return ['YYYY-WW周'];
}),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getDatePickerCellValue, () => {
return ['YYYY-WW周'];
}),
};

18
apps/vue/src/components/VxeTable/src/components/AYearPicker.tsx

@ -0,0 +1,18 @@
import { getDatePickerCellValue } from './ADatePicker';
import {
createEditRender,
createCellRender,
createFormItemRender,
createExportMethod,
} from './common';
export default {
renderEdit: createEditRender(),
renderCell: createCellRender(getDatePickerCellValue, () => {
return ['YYYY'];
}),
renderItemContent: createFormItemRender(),
exportMethod: createExportMethod(getDatePickerCellValue, () => {
return ['YYYY'];
}),
};

427
apps/vue/src/components/VxeTable/src/components/common.tsx

@ -0,0 +1,427 @@
import { ComponentOptions, h } from 'vue';
import {
FormItemContentRenderParams,
FormItemRenderOptions,
VxeGlobalRendererHandles,
} from 'vxe-table';
import XEUtils from 'xe-utils';
import { componentMap } from '../componentMap';
import { ComponentType } from '../componentType';
import { createPlaceholderMessage } from '../helper';
/**
* @description:
*/
export function getComponent(componentName) {
const Component = componentMap.get(componentName as ComponentType);
if (!Component) throw `您还没注册此组件 ${componentName}`;
return Component as ComponentOptions;
}
export function isEmptyValue(cellValue: any) {
return cellValue === null || cellValue === undefined || cellValue === '';
}
export function formatText(cellValue: any) {
return '' + (isEmptyValue(cellValue) ? '' : cellValue);
}
export function cellText(cellValue: any): string[] {
return [formatText(cellValue)];
}
/**
* @description:
*/
export function getOnName(type: string) {
return 'on' + type.substring(0, 1).toLocaleUpperCase() + type.substring(1);
}
/**
* @description:
*/
function getModelKey(renderOpts: VxeGlobalRendererHandles.RenderOptions) {
let prop = 'value';
switch (renderOpts.name) {
case 'ASwitch':
prop = 'checked';
break;
}
return prop;
}
/**
* @description:
*/
function getModelEvent(renderOpts: VxeGlobalRendererHandles.RenderOptions) {
let type = 'update:value';
switch (renderOpts.name) {
case 'ASwitch':
type = 'update:checked';
break;
}
return type;
}
/**
* @description: chang值改变方法
* @param {}
* @return {*}
* @author: *
*/
function getChangeEvent() {
return 'change';
}
function getClickEvent() {
return 'click';
}
/**
* @description:
* @param {}
* @return {*}
* @author: *
*/
export function createEvents(
renderOpts: VxeGlobalRendererHandles.RenderOptions,
params: VxeGlobalRendererHandles.RenderParams,
inputFunc?: Function,
changeFunc?: Function,
clickFunc?: Function,
) {
const { events } = renderOpts;
const modelEvent = getModelEvent(renderOpts);
const changeEvent = getChangeEvent();
const clickEvent = getClickEvent();
const isSameEvent = changeEvent === modelEvent;
const ons: { [type: string]: Function } = {};
XEUtils.objectEach(events, (func: Function, key: string) => {
ons[getOnName(key)] = function (...args: any[]) {
func(params, ...args);
};
});
if (inputFunc) {
ons[getOnName(modelEvent)] = function (targetEvnt: any) {
inputFunc(targetEvnt);
if (events && events[modelEvent]) {
events[modelEvent](params, targetEvnt);
}
if (isSameEvent && changeFunc) {
changeFunc(targetEvnt);
}
};
}
if (!isSameEvent && changeFunc) {
ons[getOnName(changeEvent)] = function (...args: any[]) {
changeFunc(...args);
if (events && events[changeEvent]) {
events[changeEvent](params, ...args);
}
};
}
if (clickFunc) {
ons[getOnName(clickEvent)] = function (...args: any[]) {
clickFunc(...args);
if (events && events[clickEvent]) {
events[clickEvent](params, ...args);
}
};
}
return ons;
}
/**
* @description:
*/
export function createProps(
renderOpts: VxeGlobalRendererHandles.RenderOptions,
value: any,
defaultProps?: { [prop: string]: any },
) {
const name = renderOpts.name as ComponentType;
return XEUtils.assign(
{
placeholder: createPlaceholderMessage(name),
allowClear: true,
},
defaultProps,
renderOpts.props,
{
[getModelKey(renderOpts)]: value,
},
);
}
/**
* @description:
*/
export function createDefaultRender(
defaultProps?: { [key: string]: any },
callBack?: (
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
params: VxeGlobalRendererHandles.RenderDefaultParams,
) => Record<string, any>,
) {
return function (
renderOpts: VxeGlobalRendererHandles.RenderDefaultOptions,
params: VxeGlobalRendererHandles.RenderDefaultParams,
) {
const { row, column, $table } = params;
const { name, attrs } = renderOpts;
const cellValue = XEUtils.get(row, column.field as string);
const args = (callBack && callBack(renderOpts, params)) ?? {};
const Component = getComponent(name);
return [
h(Component, {
...attrs,
...createProps(renderOpts, cellValue, defaultProps),
...args,
...createEvents(
renderOpts,
params,
(value: any) => XEUtils.set(row, column.field as string, value),
() => $table.updateStatus(params),
),
}),
];
};
}
/**
* @description:
*/
export function createEditRender(
defaultProps?: { [key: string]: any },
callBack?: (
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
params: VxeGlobalRendererHandles.RenderEditParams,
) => Record<string, any>,
) {
return function (
renderOpts: VxeGlobalRendererHandles.RenderEditOptions,
params: VxeGlobalRendererHandles.RenderEditParams,
) {
const { row, column, $table } = params;
const { name, attrs } = renderOpts;
const cellValue = XEUtils.get(row, column.field as string);
const args = (callBack && callBack(renderOpts, params)) ?? {};
const Component = getComponent(name);
return [
h(Component, {
...attrs,
...createProps(renderOpts, cellValue, defaultProps),
...args,
...createEvents(
renderOpts,
params,
(value: any) => XEUtils.set(row, column.field as string, value),
() => $table.updateStatus(params),
),
}),
];
};
}
/**
* @description:
*/
export function createFilterRender(
defaultProps?: { [key: string]: any },
callBack?: (
renderOpts: VxeGlobalRendererHandles.RenderFilterOptions,
params: VxeGlobalRendererHandles.RenderFilterParams,
) => Record<string, any>,
) {
return function (
renderOpts: VxeGlobalRendererHandles.RenderFilterOptions,
params: VxeGlobalRendererHandles.RenderFilterParams,
) {
const { column } = params;
const { name, attrs } = renderOpts;
const args = (callBack && callBack(renderOpts, params)) ?? {};
const Component = getComponent(name);
return [
h(
'div',
{
class: 'vxe-table--filter-antd-wrapper',
},
column.filters.map((option, oIndex) => {
const optionValue = option.data;
const checked = !!option.data;
return h(Component, {
key: oIndex,
...attrs,
...createProps(renderOpts, optionValue, defaultProps),
...args,
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
option.data = value;
},
() => {
// 处理 change 事件相关逻辑
const { $panel } = params;
$panel.changeOption(null, checked, option);
},
),
});
}),
),
];
};
}
/**
* @description:
* @param {}
* @return {*}
* @author: *
*/
export function createDefaultFilterRender() {
return function (params: VxeGlobalRendererHandles.FilterMethodParams) {
const { option, row, column } = params;
const { data } = option;
const cellValue = XEUtils.get(row, column.field as string);
return cellValue === data;
};
}
/**
* @description: form表单渲染
*/
export function createFormItemRender(
defaultProps?: { [key: string]: any },
callBack?: (
renderOpts: FormItemRenderOptions,
params: FormItemContentRenderParams,
) => Record<string, any>,
) {
return function (renderOpts: FormItemRenderOptions, params: FormItemContentRenderParams) {
const args = (callBack && callBack(renderOpts, params)) ?? {};
const { data, property, $form } = params;
const { name } = renderOpts;
const { attrs } = renderOpts;
const itemValue = XEUtils.get(data, property);
const Component = getComponent(name);
return [
h(Component, {
...attrs,
...createProps(renderOpts, itemValue, defaultProps),
...args,
...createEvents(
renderOpts,
params,
(value: any) => {
// 处理 model 值双向绑定
XEUtils.set(data, property, value);
},
() => {
// 处理 change 事件相关逻辑
$form.updateStatus({
...params,
field: property,
});
},
),
}),
];
};
}
/**
* @description: cell渲染
*/
export function createCellRender(
getSelectCellValue: Function,
callBack?: (
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
params: VxeGlobalRendererHandles.RenderCellParams,
) => Array<any>,
) {
return function (
renderOpts: VxeGlobalRendererHandles.RenderCellOptions,
params: VxeGlobalRendererHandles.RenderCellParams,
) {
const args = (callBack && callBack(renderOpts, params)) ?? [];
const cellLabel = getSelectCellValue && getSelectCellValue(renderOpts, params, ...args);
const { placeholder } = renderOpts;
return [
h(
'span',
{
class: 'vxe-cell--label',
},
placeholder && isEmptyValue(cellLabel)
? [
h(
'span',
{
class: 'vxe-cell--placeholder',
},
formatText(placeholder),
),
]
: formatText(cellLabel),
),
];
};
}
/**
* @description:
* @param {}
* @return {*}
* @author: *
*/
export function createExportMethod(
getExportCellValue: Function,
callBack?: (params: VxeGlobalRendererHandles.ExportMethodParams) => Array<any>,
) {
return function (params: VxeGlobalRendererHandles.ExportMethodParams) {
const { row, column, options } = params;
const args = (callBack && callBack(params)) ?? [];
return options && options.original
? XEUtils.get(row, column.field as string)
: getExportCellValue(column.editRender || column.cellRender, params, ...args);
};
}
/**
* @description:
*/
export function createToolbarToolRender(
defaultProps?: { [key: string]: any },
callBack?: (
renderOpts: VxeGlobalRendererHandles.RenderToolOptions,
params: VxeGlobalRendererHandles.RenderToolParams,
) => Record<string, any>,
) {
return function (
renderOpts: VxeGlobalRendererHandles.RenderToolOptions,
params: VxeGlobalRendererHandles.RenderToolParams,
) {
const { name, attrs } = renderOpts;
const args = (callBack && callBack(renderOpts, params)) ?? {};
const Component = getComponent(name);
return [
h(Component, {
...attrs,
...createProps(renderOpts, null, defaultProps),
...args,
...createEvents(renderOpts, params),
}),
];
};
}

112
apps/vue/src/components/VxeTable/src/components/index.tsx

@ -0,0 +1,112 @@
import { VXETableCore, VxeGlobalInterceptorHandles } from 'vxe-table';
import AAutoComplete from './AAutoComplete';
import AInput from './AInput';
import AInputNumber from './AInputNumber';
import ASelect from './ASelect';
import ACascader from './ACascader';
import ADatePicker from './ADatePicker';
import AMonthPicker from './AMonthPicker';
import ARangePicker from './ARangePicker';
import AWeekPicker from './AWeekPicker';
import ATreeSelect from './ATreeSelect';
import ATimePicker from './ATimePicker';
import ARate from './ARate';
import ASwitch from './ASwitch';
import ARadioGroup from './ARadioGroup';
import ACheckboxGroup from './ACheckboxGroup';
import AButton from './AButton';
import AButtonGroup from './AButtonGroup';
import AApiSelect from './AApiSelect';
import AEmpty from './AEmpty';
import AInputSearch from './AInputSearch';
import AYearPicker from './AYearPicker';
/**
*
*/
function getEventTargetNode(evnt: any, container: HTMLElement, className: string) {
let targetElem;
let target = evnt.target;
while (target && target.nodeType && target !== document) {
if (
className &&
target.className &&
target.className.split &&
target.className.split(' ').indexOf(className) > -1
) {
targetElem = target;
} else if (target === container) {
return { flag: className ? !!targetElem : true, container, targetElem: targetElem };
}
target = target.parentNode;
}
return { flag: false };
}
/**
*
*/
function handleClearEvent(
params:
| VxeGlobalInterceptorHandles.InterceptorClearFilterParams
| VxeGlobalInterceptorHandles.InterceptorClearActivedParams
| VxeGlobalInterceptorHandles.InterceptorClearAreasParams,
) {
const { $event } = params;
const bodyElem = document.body;
if (
// 下拉框
getEventTargetNode($event, bodyElem, 'ant-select-dropdown').flag ||
// 级联
getEventTargetNode($event, bodyElem, 'ant-cascader-menus').flag ||
// 日期
getEventTargetNode($event, bodyElem, 'ant-calendar-picker-container').flag ||
// 时间选择
getEventTargetNode($event, bodyElem, 'ant-time-picker-panel').flag
) {
return false;
}
}
/**
* vxe-table ant-design-vue
*/
export const VXETablePluginAntd = {
install(vxetablecore: VXETableCore) {
const { interceptor, renderer } = vxetablecore;
renderer.mixin({
AAutoComplete,
AInput,
AInputNumber,
ASelect,
ACascader,
ADatePicker,
AMonthPicker,
ARangePicker,
AWeekPicker,
ATimePicker,
ATreeSelect,
ARate,
ASwitch,
ARadioGroup,
ACheckboxGroup,
AButton,
AButtonGroup,
AApiSelect,
AEmpty,
AInputSearch,
AYearPicker,
});
interceptor.add('event.clearFilter', handleClearEvent);
interceptor.add('event.clearActived', handleClearEvent);
interceptor.add('event.clearAreas', handleClearEvent);
},
};
if (typeof window !== 'undefined' && window.VXETable && window.VXETable.use) {
window.VXETable.use(VXETablePluginAntd);
}
export default VXETablePluginAntd;

4
apps/vue/src/components/VxeTable/src/const.ts

@ -0,0 +1,4 @@
/**
* @description: vxe-table prop
*/
export const ignorePropKeys = ['tableClass', 'tableStyle'];

8
apps/vue/src/components/VxeTable/src/css/common.scss

@ -0,0 +1,8 @@
*,
::before,
::after {
box-sizing: border-box;
border-width: 0;
border-style: solid;
border-color: initial;
}

105
apps/vue/src/components/VxeTable/src/css/component.scss

@ -0,0 +1,105 @@
%ResetBorder {
border: 0;
box-shadow: none;
}
%CompWidth {
& > .ant-input,
& > .ant-input-number,
& > .ant-select,
& > .ant-cascader-picker,
& > .ant-calendar-picker,
& > .ant-time-picker {
width: 100%;
}
}
.vxe-form {
.vxe-form--item-content {
@extend %CompWidth;
}
}
.vxe-table--filter-antd-wrapper {
& > .ant-input,
& > .ant-input-number,
& > .ant-select,
& > .ant-rate {
width: 180px;
}
}
.vxe-cell,
.vxe-tree-cell {
@extend %CompWidth;
& > .ant-rate {
vertical-align: bottom;
.anticon-star {
display: block;
}
}
}
.col--valid-error {
& > .vxe-cell,
& > .vxe-tree-cell {
& > .ant-input,
& > .ant-select .ant-input,
& > .ant-select .ant-select-selection,
& > .ant-input-number,
& > .ant-cascader-picker .ant-cascader-input,
& > .ant-calendar-picker .ant-calendar-picker-input {
// border-color: $vxe-table-validate-error-color;
box-shadow: none;
}
}
}
.vxe-table.cell--highlight {
.vxe-cell,
.vxe-tree-cell {
& > .ant-input,
& > .ant-input-number {
padding: 0;
@extend %ResetBorder;
}
& > .ant-select {
.ant-input {
padding: 0;
@extend %ResetBorder;
}
}
& > .ant-input-number {
.ant-input-number-input {
padding: 0;
}
.ant-input-number-handler-wrap,
.ant-input-number-handler-down {
@extend %ResetBorder;
}
}
& > .ant-select {
.ant-select-selection {
@extend %ResetBorder;
.ant-select-selection__rendered {
margin: 0;
}
}
}
& > .ant-cascader-picker {
.ant-input {
@extend %ResetBorder;
}
.ant-cascader-picker-label {
padding: 0;
}
}
& > .ant-calendar-picker {
.ant-calendar-picker-input {
padding: 0;
@extend %ResetBorder;
}
}
& > .ant-time-picker {
.ant-time-picker-input {
padding: 0;
@extend %ResetBorder;
}
}
}
}

6
apps/vue/src/components/VxeTable/src/css/index.scss

@ -0,0 +1,6 @@
@import './common.scss';
@import './variable.scss';
@import './scrollbar.scss';
@import './toolbar.scss';
@import './component.scss';
@import 'vxe-table/styles/index.scss';

24
apps/vue/src/components/VxeTable/src/css/scrollbar.scss

@ -0,0 +1,24 @@
.vxe-grid_scrollbar {
::-webkit-scrollbar {
width: 8px;
height: 8px;
}
::-webkit-scrollbar-track {
background-color: #ffffff;
}
::-webkit-scrollbar-thumb {
background-color: rgba(0, 0, 0, 0.1);
border-radius: 5px;
border: 1px solid #f1f1f1;
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
}
::-webkit-scrollbar-thumb:hover {
background-color: #a8a8a8;
}
::-webkit-scrollbar-thumb:active {
background-color: #a8a8a8;
}
::-webkit-scrollbar-corner {
background-color: #ffffff;
}
}

30
apps/vue/src/components/VxeTable/src/css/toolbar.scss

@ -0,0 +1,30 @@
.vxe-toolbar .vxe-custom--option-wrapper .vxe-custom--footer {
display: flex;
}
.vxe-toolbar .vxe-tools--wrapper,
.vxe-toolbar .vxe-tools--operate button:first-child {
margin: 0;
}
.vxe-toolbar .vxe-tools--wrapper,
.vxe-toolbar .vxe-tools--operate .vxe-button {
margin-left: 1px;
border-radius: 0 !important;
}
.vxe-toolbar .vxe-tools--wrapper,
.vxe-toolbar .vxe-tools--operate button:first-child {
margin-left: 10px;
}
.vxe-toolbar .vxe-tools--wrapper,
.vxe-toolbar .vxe-tools--operate .vxe-custom--wrapper {
margin-left: 1px;
border-radius: 0 !important;
}
.vxe-toolbar .vxe-tools--wrapper,
.vxe-toolbar .vxe-tools--operate .vxe-custom--wrapper .vxe-button {
margin-left: 1px;
}

6
apps/vue/src/components/VxeTable/src/css/variable.scss

@ -0,0 +1,6 @@
$vxe-primary-color: rgb(9, 96, 189) !default;
$vxe-table-row-current-background-color: rgba(9, 96, 189, 0.3);
$vxe-table-row-hover-current-background-color: rgba(9, 96, 189, 0.2);
$vxe-table-column-hover-background-color: rgba(9, 96, 189, 0.3);
$vxe-table-column-current-background-color: rgba(9, 96, 189, 0.2);
$vxe-table-validate-error-color: #f56c6c;

17
apps/vue/src/components/VxeTable/src/emits.ts

@ -0,0 +1,17 @@
import tableEmits from 'vxe-table/es/table/src/emits';
export const basicEmits = [
...tableEmits,
'page-change',
'form-submit',
'form-submit-invalid',
'form-reset',
'form-collapse',
'form-toggle-collapse',
'toolbar-button-click',
'toolbar-tool-click',
'zoom',
//... 如有缺少在此处追加
// xxx
];

19
apps/vue/src/components/VxeTable/src/helper.ts

@ -0,0 +1,19 @@
import { ComponentType } from './componentType';
import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n();
/**
* @description: placeholder
*/
export function createPlaceholderMessage(component: ComponentType) {
if (!component) return;
if (component.includes('RangePicker')) {
return [t('common.chooseText'), t('common.chooseText')];
}
if (component.includes('Input') || component.includes('Complete') || component.includes('Rate')) {
return t('common.inputText');
} else {
return t('common.chooseText');
}
}

131
apps/vue/src/components/VxeTable/src/methods.ts

@ -0,0 +1,131 @@
import { GridMethods, TableMethods } from 'vxe-table';
export const gridComponentMethodKeys: (keyof GridMethods | keyof TableMethods)[] = [
// vxe-grid 部分
'dispatchEvent',
'commitProxy',
'getFormItems',
'getPendingRecords',
'zoom',
'isMaximized',
'maximize',
'revert',
'getProxyInfo',
// vxe-table和vxe-grid公共部分
'clearAll',
'syncData',
'updateData',
'loadData',
'reloadData',
'reloadRow',
'loadColumn',
'reloadColumn',
'getRowNode',
'getColumnNode',
'getRowIndex',
'getVTRowIndex',
'getVMRowIndex',
'getColumnIndex',
'getVTColumnIndex',
'getVMColumnIndex',
'createData',
'createRow',
'revertData',
'clearData',
'isInsertByRow',
'isUpdateByRow',
'getColumns',
'getColumnById',
'getColumnByField',
'getTableColumn',
'getData',
'getCheckboxRecords',
'getParentRow',
'getRowSeq',
'getRowById',
'getRowid',
'getTableData',
'hideColumn',
'showColumn',
'resetColumn',
'refreshColumn',
'refreshScroll',
'recalculate',
'closeTooltip',
'isAllCheckboxChecked',
'isAllCheckboxIndeterminate',
'getCheckboxIndeterminateRecords',
'setCheckboxRow',
'isCheckedByCheckboxRow',
'isIndeterminateByCheckboxRow',
'toggleCheckboxRow',
'setAllCheckboxRow',
'getRadioReserveRecord',
'clearRadioReserve',
'getCheckboxReserveRecords',
'clearCheckboxReserve',
'toggleAllCheckboxRow',
'clearCheckboxRow',
'setCurrentRow',
'isCheckedByRadioRow',
'setRadioRow',
'clearCurrentRow',
'clearRadioRow',
'getCurrentRecord',
'getRadioRecord',
'getCurrentColumn',
'setCurrentColumn',
'clearCurrentColumn',
'sort',
'clearSort',
'isSort',
'getSortColumns',
'closeFilter',
'isFilter',
'isRowExpandLoaded',
'clearRowExpandLoaded',
'reloadRowExpand',
'reloadRowExpand',
'toggleRowExpand',
'setAllRowExpand',
'setRowExpand',
'isExpandByRow',
'clearRowExpand',
'clearRowExpandReserve',
'getRowExpandRecords',
'getTreeExpandRecords',
'isTreeExpandLoaded',
'clearTreeExpandLoaded',
'reloadTreeExpand',
'reloadTreeChilds',
'toggleTreeExpand',
'setAllTreeExpand',
'setTreeExpand',
'isTreeExpandByRow',
'clearTreeExpand',
'clearTreeExpandReserve',
'getScroll',
'scrollTo',
'scrollToRow',
'scrollToColumn',
'clearScroll',
'updateFooter',
'updateStatus',
'setMergeCells',
'removeInsertRow',
'removeMergeCells',
'getMergeCells',
'clearMergeCells',
'setMergeFooterItems',
'removeMergeFooterItems',
'getMergeFooterItems',
'clearMergeFooterItems',
'openTooltip',
'focus',
'blur',
'connect',
//... 如有缺少在此处追加
// xxx
];

52
apps/vue/src/components/VxeTable/src/props.ts

@ -0,0 +1,52 @@
import { VxeGridPropTypes, VxeTablePropTypes } from 'vxe-table';
import tableProps from 'vxe-table/es/table/src/props';
import { CSSProperties } from 'vue';
/**
* @description: table二次开发需要后prop属性
*/
export const basicProps = {
...tableProps,
columns: Array as PropType<VxeGridPropTypes.Columns>,
pagerConfig: {
type: Object as PropType<VxeGridPropTypes.PagerConfig>,
default: () => ({}),
},
proxyConfig: {
type: Object as PropType<VxeGridPropTypes.ProxyConfig>,
default: () => ({}),
},
toolbarConfig: {
type: Object as PropType<VxeGridPropTypes.ToolbarConfig>,
default: () => ({}),
},
formConfig: {
type: Object as PropType<VxeGridPropTypes.FormConfig>,
default: () => ({}),
},
zoomConfig: {
type: Object as PropType<VxeGridPropTypes.ZoomConfig>,
default: () => ({}),
},
printConfig: {
type: Object as PropType<VxeTablePropTypes.PrintConfig>,
default: () => ({}),
},
exportConfig: {
type: Object as PropType<VxeTablePropTypes.ExportConfig>,
default: () => ({}),
},
importConfig: {
type: Object as PropType<VxeTablePropTypes.ImportConfig>,
default: () => ({}),
},
size: String as PropType<VxeGridPropTypes.Size>,
tableClass: {
type: String,
default: '',
},
tableStyle: {
type: Object as PropType<CSSProperties>,
default: () => ({}),
},
};

4
apps/vue/src/components/VxeTable/src/setting.ts

@ -0,0 +1,4 @@
import { VXETable } from '..';
import componentSetting from '/@/settings/componentSetting';
VXETable.setup(componentSetting.vxeTable);

7
apps/vue/src/components/VxeTable/src/types.ts

@ -0,0 +1,7 @@
import { CSSProperties } from 'vue';
import { VxeGridProps } from 'vxe-table';
export type BasicTableProps = VxeGridProps & {
tableClass?: string;
tableStyle?: CSSProperties;
};

3
apps/vue/src/components/registerGlobComp.ts

@ -56,6 +56,7 @@ import {
Input as AInput,
InputNumber as AInputNumber,
} from 'ant-design-vue';
import VXETable from 'vxe-table';
const compList = [
Affix,
@ -157,5 +158,5 @@ export function registerGlobComp(app: App) {
app.component(comp.name || comp.displayName, comp);
});
app.use(Input).use(Button).use(Layout);
app.use(Input).use(Button).use(Layout).use(VXETable);
}

1
apps/vue/src/main.ts

@ -1,6 +1,7 @@
import 'virtual:windi-base.css';
import 'virtual:windi-components.css';
import '/@/design/index.less';
import '/@/components/VxeTable/src/css/index.scss';
import 'virtual:windi-utilities.css';
// Register icon sprite
import 'virtual:svg-icons-register';

46
apps/vue/src/settings/componentSetting.ts

@ -52,6 +52,52 @@ export default {
return data;
},
},
vxeTable: {
table: {
border: true,
stripe: true,
columnConfig: {
resizable: true,
isCurrent: true,
isHover: true,
},
rowConfig: {
isCurrent: true,
isHover: true,
},
emptyRender: {
name: 'AEmpty',
},
printConfig: {},
exportConfig: {},
customConfig: {
storage: true,
},
},
grid: {
toolbarConfig: {
enabled: true,
export: true,
zoom: true,
print: true,
refresh: true,
custom: true,
},
pagerConfig: {
pageSizes: [20, 50, 100, 500],
pageSize: 20,
autoHidden: true,
},
proxyConfig: {
form: true,
props: {
result: 'items',
total: 'total',
},
},
zoomConfig: {},
},
},
// scrollbar setting
scrollbar: {
// Whether to use native scroll bar

Loading…
Cancel
Save