UNPKG

@blueking/vxe-table

Version:

一个基于 vue 的 PC 端表格组件,支持增删改查、虚拟树、列拖拽,懒加载、快捷菜单、数据校验、树形结构、打印、导入导出、自定义模板、渲染器、JSON 配置式...

1,390 lines (1,389 loc) 56.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _vue = require("vue"); var _xeUtils = _interopRequireDefault(require("xe-utils")); var _utils = require("../../ui/src/utils"); var _dom = require("../../ui/src/dom"); var _ui = require("../../ui"); var _table = _interopRequireDefault(require("../../table")); var _toolbar = _interopRequireDefault(require("../../toolbar")); var _props = _interopRequireDefault(require("../../table/src/props")); var _emits = _interopRequireDefault(require("../../table/src/emits")); var _vn = require("../../ui/src/vn"); var _log = require("../../ui/src/log"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } const { getConfig, getI18n, commands, hooks, useFns, createEvent, globalEvents, GLOBAL_EVENT_KEYS, renderEmptyElement } = _ui.VxeUI; const tableComponentPropKeys = Object.keys(_props.default); const tableComponentMethodKeys = ['clearAll', 'syncData', 'updateData', 'loadData', 'reloadData', 'reloadRow', 'loadColumn', 'reloadColumn', 'getRowNode', 'getColumnNode', 'getRowIndex', 'getVTRowIndex', 'getVMRowIndex', 'getColumnIndex', 'getVTColumnIndex', 'getVMColumnIndex', 'setRow', 'createData', 'createRow', 'revertData', 'clearData', 'isInsertByRow', 'isUpdateByRow', 'getColumns', 'getColumnById', 'getColumnByField', 'getTableColumn', 'getFullColumns', 'getData', 'getCheckboxRecords', 'getParentRow', 'getTreeParentRow', 'getRowSeq', 'getRowById', 'getRowid', 'getTableData', 'getFullData', 'setColumnFixed', 'clearColumnFixed', 'setColumnWidth', 'getColumnWidth', 'hideColumn', 'showColumn', 'resetColumn', 'refreshColumn', 'refreshScroll', 'recalculate', 'closeTooltip', 'isAllCheckboxChecked', 'isAllCheckboxIndeterminate', 'getCheckboxIndeterminateRecords', 'setCheckboxRow', 'setCheckboxRowKey', 'isCheckedByCheckboxRow', 'isCheckedByCheckboxRowKey', 'isIndeterminateByCheckboxRow', 'isIndeterminateByCheckboxRowKey', 'toggleCheckboxRow', 'setAllCheckboxRow', 'getRadioReserveRecord', 'clearRadioReserve', 'getCheckboxReserveRecords', 'clearCheckboxReserve', 'toggleAllCheckboxRow', 'clearCheckboxRow', 'setCurrentRow', 'isCheckedByRadioRow', 'isCheckedByRadioRowKey', 'setRadioRow', 'setRadioRowKey', 'clearCurrentRow', 'clearRadioRow', 'getCurrentRecord', 'getRadioRecord', 'getCurrentColumn', 'setCurrentColumn', 'clearCurrentColumn', 'setPendingRow', 'togglePendingRow', 'getPendingRecords', 'clearPendingRow', 'sort', 'setSort', 'clearSort', 'isSort', 'getSortColumns', 'closeFilter', 'isFilter', 'isActiveFilterByColumn', 'isRowExpandLoaded', 'clearRowExpandLoaded', 'reloadRowExpand', 'reloadRowExpand', 'toggleRowExpand', 'setAllRowExpand', 'setRowExpand', 'isExpandByRow', 'isRowExpandByRow', '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', 'getCustomStoreData', 'openTooltip', 'getCellLabel', 'getCellElement', 'focus', 'blur', 'connect']; const gridComponentEmits = [..._emits.default, 'page-change', 'form-submit', 'form-submit-invalid', 'form-reset', 'form-collapse', 'form-toggle-collapse', 'proxy-query', 'proxy-delete', 'proxy-save', 'toolbar-button-click', 'toolbar-tool-click', 'zoom']; var _default = exports.default = (0, _vue.defineComponent)({ name: 'VxeGrid', props: Object.assign(Object.assign({}, _props.default), { layouts: Array, columns: Array, pagerConfig: Object, proxyConfig: Object, toolbarConfig: Object, formConfig: Object, zoomConfig: Object, size: { type: String, default: () => getConfig().grid.size || getConfig().size } }), emits: gridComponentEmits, setup(props, context) { var _a; const { slots, emit } = context; const xID = _xeUtils.default.uniqueId(); // 使用已安装的组件,如果未安装则不渲染 const VxeUIFormComponent = _ui.VxeUI.getComponent('VxeForm'); const VxeUIPagerComponent = _ui.VxeUI.getComponent('VxePager'); const defaultLayouts = [['Form'], ['Toolbar', 'Top', 'Table', 'Bottom', 'Pager']]; const { computeSize } = useFns.useSize(props); const reactData = (0, _vue.reactive)({ tableLoading: false, proxyInited: false, isZMax: false, tableData: [], filterData: [], formData: {}, sortData: [], tZindex: 0, tablePage: { total: 0, pageSize: ((_a = getConfig().pager) === null || _a === void 0 ? void 0 : _a.pageSize) || 10, currentPage: 1 } }); const refElem = (0, _vue.ref)(); const refTable = (0, _vue.ref)(); const refForm = (0, _vue.ref)(); const refToolbar = (0, _vue.ref)(); const refPager = (0, _vue.ref)(); const refFormWrapper = (0, _vue.ref)(); const refToolbarWrapper = (0, _vue.ref)(); const refTopWrapper = (0, _vue.ref)(); const refBottomWrapper = (0, _vue.ref)(); const refPagerWrapper = (0, _vue.ref)(); const extendTableMethods = methodKeys => { const funcs = {}; methodKeys.forEach(name => { funcs[name] = (...args) => { const $xeTable = refTable.value; if ($xeTable && $xeTable[name]) { return $xeTable[name](...args); } }; }); return funcs; }; const gridExtendTableMethods = extendTableMethods(tableComponentMethodKeys); tableComponentMethodKeys.forEach(name => { gridExtendTableMethods[name] = (...args) => { const $xeTable = refTable.value; if ($xeTable && $xeTable[name]) { return $xeTable && $xeTable[name](...args); } }; }); const computeProxyOpts = (0, _vue.computed)(() => { return _xeUtils.default.merge({}, _xeUtils.default.clone(getConfig().grid.proxyConfig, true), props.proxyConfig); }); const computeIsRespMsg = (0, _vue.computed)(() => { const proxyOpts = computeProxyOpts.value; return _xeUtils.default.isBoolean(proxyOpts.message) ? proxyOpts.message : proxyOpts.showResponseMsg; }); const computeIsActiveMsg = (0, _vue.computed)(() => { const proxyOpts = computeProxyOpts.value; return proxyOpts.showActiveMsg; }); const computePagerOpts = (0, _vue.computed)(() => { return Object.assign({}, getConfig().grid.pagerConfig, props.pagerConfig); }); const computeFormOpts = (0, _vue.computed)(() => { return Object.assign({}, getConfig().grid.formConfig, props.formConfig); }); const computeToolbarOpts = (0, _vue.computed)(() => { return Object.assign({}, getConfig().grid.toolbarConfig, props.toolbarConfig); }); const computeZoomOpts = (0, _vue.computed)(() => { return Object.assign({}, getConfig().grid.zoomConfig, props.zoomConfig); }); const computeStyles = (0, _vue.computed)(() => { const { height, maxHeight } = props; const { isZMax, tZindex } = reactData; const stys = {}; if (isZMax) { stys.zIndex = tZindex; } else { if (height) { stys.height = height === 'auto' || height === '100%' ? '100%' : (0, _dom.toCssUnit)(height); } if (maxHeight) { stys.maxHeight = maxHeight === 'auto' || maxHeight === '100%' ? '100%' : (0, _dom.toCssUnit)(maxHeight); } } return stys; }); const computeTableExtendProps = (0, _vue.computed)(() => { const rest = {}; const gridProps = props; tableComponentPropKeys.forEach(key => { rest[key] = gridProps[key]; }); return rest; }); const computeTableProps = (0, _vue.computed)(() => { const { seqConfig, pagerConfig, loading, editConfig, proxyConfig } = props; const { isZMax, tableLoading, tablePage, tableData } = reactData; const tableExtendProps = computeTableExtendProps.value; const proxyOpts = computeProxyOpts.value; const pagerOpts = computePagerOpts.value; const tableProps = Object.assign({}, tableExtendProps); if (isZMax) { if (tableExtendProps.maxHeight) { tableProps.maxHeight = '100%'; } else { tableProps.height = '100%'; } } if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { tableProps.loading = loading || tableLoading; tableProps.data = tableData; if (pagerConfig && proxyOpts.seq && (0, _utils.isEnableConf)(pagerOpts)) { tableProps.seqConfig = Object.assign({}, seqConfig, { startIndex: (tablePage.currentPage - 1) * tablePage.pageSize }); } } if (editConfig) { tableProps.editConfig = Object.assign({}, editConfig); } return tableProps; }); const computeCurrLayoutConf = (0, _vue.computed)(() => { const { layouts } = props; let confs = []; if (layouts && layouts.length) { confs = layouts; } else { confs = getConfig().grid.layouts || defaultLayouts; } let headKeys = []; let bodyKeys = []; let footKeys = []; if (confs.length) { if (_xeUtils.default.isArray(confs[0])) { headKeys = confs[0]; bodyKeys = confs[1] || []; footKeys = confs[2] || []; } else { bodyKeys = confs; } } return { headKeys, bodyKeys, footKeys }; }); const computePageConfFlag = (0, _vue.computed)(() => { const pagerOpts = computePagerOpts.value; return `${pagerOpts.currentPage}${pagerOpts.pageSize}`; }); const refMaps = { refElem, refTable, refForm, refToolbar, refPager }; const computeMaps = { computeProxyOpts, computePagerOpts, computeFormOpts, computeToolbarOpts, computeZoomOpts }; const $xeGrid = { xID, props: props, context, reactData, getRefMaps: () => refMaps, getComputeMaps: () => computeMaps }; const initToolbar = () => { const toolbarOpts = computeToolbarOpts.value; if (props.toolbarConfig && (0, _utils.isEnableConf)(toolbarOpts)) { (0, _vue.nextTick)(() => { const $xeTable = refTable.value; const $xeToolbar = refToolbar.value; if ($xeTable && $xeToolbar) { $xeTable.connect($xeToolbar); } }); } }; const getFormData = () => { const { proxyConfig } = props; const { formData } = reactData; const proxyOpts = computeProxyOpts.value; const formOpts = computeFormOpts.value; return proxyConfig && (0, _utils.isEnableConf)(proxyOpts) && proxyOpts.form ? formData : formOpts.data; }; const initPages = () => { const { tablePage } = reactData; const { pagerConfig } = props; const pagerOpts = computePagerOpts.value; const { currentPage, pageSize } = pagerOpts; if (pagerConfig && (0, _utils.isEnableConf)(pagerOpts)) { if (currentPage) { tablePage.currentPage = currentPage; } if (pageSize) { tablePage.pageSize = pageSize; } } }; const triggerPendingEvent = code => { const isActiveMsg = computeIsActiveMsg.value; const $xeTable = refTable.value; const selectRecords = $xeTable.getCheckboxRecords(); if (selectRecords.length) { $xeTable.togglePendingRow(selectRecords); gridExtendTableMethods.clearCheckboxRow(); } else { if (isActiveMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' }); } } } }; const getRespMsg = (rest, defaultMsg) => { const proxyOpts = computeProxyOpts.value; const resConfigs = proxyOpts.response || proxyOpts.props || {}; const messageProp = resConfigs.message; let msg; if (rest && messageProp) { msg = _xeUtils.default.isFunction(messageProp) ? messageProp({ data: rest, $grid: $xeGrid }) : _xeUtils.default.get(rest, messageProp); } return msg || getI18n(defaultMsg); }; const handleDeleteRow = (code, alertKey, callback) => { const isActiveMsg = computeIsActiveMsg.value; const selectRecords = gridExtendTableMethods.getCheckboxRecords(); if (isActiveMsg) { if (selectRecords.length) { if (_ui.VxeUI.modal) { return _ui.VxeUI.modal.confirm({ id: `cfm_${code}`, content: getI18n(alertKey), escClosable: true }).then(type => { if (type === 'confirm') { return callback(); } }); } } else { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: `msg_${code}`, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' }); } } } else { if (selectRecords.length) { callback(); } } return Promise.resolve(); }; const pageChangeEvent = params => { const { proxyConfig } = props; const { tablePage } = reactData; const { $event, currentPage, pageSize } = params; const proxyOpts = computeProxyOpts.value; tablePage.currentPage = currentPage; tablePage.pageSize = pageSize; gridMethods.dispatchEvent('page-change', params, $event); if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { gridMethods.commitProxy('query').then(rest => { gridMethods.dispatchEvent('proxy-query', rest, $event); }); } }; const sortChangeEvent = params => { const $xeTable = refTable.value; const { proxyConfig } = props; const { computeSortOpts } = $xeTable.getComputeMaps(); const proxyOpts = computeProxyOpts.value; const sortOpts = computeSortOpts.value; // 如果是服务端排序 if (sortOpts.remote) { reactData.sortData = params.sortList; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { reactData.tablePage.currentPage = 1; gridMethods.commitProxy('query').then(rest => { gridMethods.dispatchEvent('proxy-query', rest, params.$event); }); } } gridMethods.dispatchEvent('sort-change', params, params.$event); }; const filterChangeEvent = params => { const $xeTable = refTable.value; const { proxyConfig } = props; const { computeFilterOpts } = $xeTable.getComputeMaps(); const proxyOpts = computeProxyOpts.value; const filterOpts = computeFilterOpts.value; // 如果是服务端过滤 if (filterOpts.remote) { reactData.filterData = params.filterList; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { reactData.tablePage.currentPage = 1; gridMethods.commitProxy('query').then(rest => { gridMethods.dispatchEvent('proxy-query', rest, params.$event); }); } } gridMethods.dispatchEvent('filter-change', params, params.$event); }; const submitFormEvent = params => { const { proxyConfig } = props; const proxyOpts = computeProxyOpts.value; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { gridMethods.commitProxy('reload').then(rest => { gridMethods.dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isReload: true }), params.$event); }); } gridMethods.dispatchEvent('form-submit', params, params.$event); }; const resetFormEvent = params => { const { proxyConfig } = props; const { $event } = params; const proxyOpts = computeProxyOpts.value; const $xeTable = refTable.value; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { $xeTable.clearScroll(); gridMethods.commitProxy('reload').then(rest => { gridMethods.dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isReload: true }), $event); }); } gridMethods.dispatchEvent('form-reset', params, $event); }; const submitInvalidEvent = params => { gridMethods.dispatchEvent('form-submit-invalid', params, params.$event); }; const collapseEvent = params => { const { $event } = params; (0, _vue.nextTick)(() => gridExtendTableMethods.recalculate(true)); gridMethods.dispatchEvent('form-toggle-collapse', params, $event); gridMethods.dispatchEvent('form-collapse', params, $event); }; const handleZoom = isMax => { const { isZMax } = reactData; if (isMax ? !isZMax : isZMax) { reactData.isZMax = !isZMax; if (reactData.tZindex < (0, _utils.getLastZIndex)()) { reactData.tZindex = (0, _utils.nextZIndex)(); } } return (0, _vue.nextTick)().then(() => gridExtendTableMethods.recalculate(true)).then(() => { setTimeout(() => gridExtendTableMethods.recalculate(true), 15); return reactData.isZMax; }); }; const getFuncSlot = (optSlots, slotKey) => { const funcSlot = optSlots[slotKey]; if (funcSlot) { if (_xeUtils.default.isString(funcSlot)) { if (slots[funcSlot]) { return slots[funcSlot]; } else { if (process.env.NODE_ENV === 'development') { (0, _log.errLog)('vxe.error.notSlot', [funcSlot]); } } } else { return funcSlot; } } return null; }; /** * 渲染表单 */ const renderForm = () => { const { formConfig, proxyConfig } = props; const { formData } = reactData; const proxyOpts = computeProxyOpts.value; const formOpts = computeFormOpts.value; if (formConfig && (0, _utils.isEnableConf)(formOpts) || slots.form) { let slotVNs = []; if (slots.form) { slotVNs = slots.form({ $grid: $xeGrid }); } else { if (formOpts.items) { const formSlots = {}; if (!formOpts.inited) { formOpts.inited = true; const beforeItem = proxyOpts.beforeItem; if (proxyOpts && beforeItem) { formOpts.items.forEach(item => { beforeItem({ $grid: $xeGrid, item }); }); } } // 处理插槽 formOpts.items.forEach(item => { _xeUtils.default.each(item.slots, func => { if (!_xeUtils.default.isFunction(func)) { if (slots[func]) { formSlots[func] = slots[func]; } } }); }); if (VxeUIFormComponent) { slotVNs.push((0, _vue.h)(VxeUIFormComponent, Object.assign(Object.assign({ ref: refForm }, Object.assign({}, formOpts, { data: proxyConfig && (0, _utils.isEnableConf)(proxyOpts) && proxyOpts.form ? formData : formOpts.data })), { onSubmit: submitFormEvent, onReset: resetFormEvent, onSubmitInvalid: submitInvalidEvent, onCollapse: collapseEvent }), formSlots)); } } } return (0, _vue.h)('div', { ref: refFormWrapper, key: 'form', class: 'vxe-grid--form-wrapper' }, slotVNs); } return (0, _vue.createCommentVNode)(); }; /** * 渲染工具栏 */ const renderToolbar = () => { const { toolbarConfig } = props; const toolbarOpts = computeToolbarOpts.value; if (toolbarConfig && (0, _utils.isEnableConf)(toolbarOpts) || slots.toolbar) { let slotVNs = []; if (slots.toolbar) { slotVNs = slots.toolbar({ $grid: $xeGrid }); } else { const toolbarOptSlots = toolbarOpts.slots; let buttonsSlot; let toolsSlot; const toolbarSlots = {}; if (toolbarOptSlots) { buttonsSlot = getFuncSlot(toolbarOptSlots, 'buttons'); toolsSlot = getFuncSlot(toolbarOptSlots, 'tools'); if (buttonsSlot) { toolbarSlots.buttons = buttonsSlot; } if (toolsSlot) { toolbarSlots.tools = toolsSlot; } } slotVNs.push((0, _vue.h)(_toolbar.default, Object.assign({ ref: refToolbar }, toolbarOpts), toolbarSlots)); } return (0, _vue.h)('div', { ref: refToolbarWrapper, key: 'toolbar', class: 'vxe-grid--toolbar-wrapper' }, slotVNs); } return (0, _vue.createCommentVNode)(); }; /** * 渲染表格顶部区域 */ const renderTop = () => { if (slots.top) { return (0, _vue.h)('div', { ref: refTopWrapper, key: 'top', class: 'vxe-grid--top-wrapper' }, slots.top({ $grid: $xeGrid })); } return (0, _vue.createCommentVNode)(); }; const renderTableLeft = () => { const leftSlot = slots.left; if (leftSlot) { return (0, _vue.h)('div', { class: 'vxe-grid--left-wrapper' }, leftSlot({ $grid: $xeGrid })); } return (0, _vue.createCommentVNode)(); }; const renderTableRight = () => { const rightSlot = slots.right; if (rightSlot) { return (0, _vue.h)('div', { class: 'vxe-grid--right-wrapper' }, rightSlot({ $grid: $xeGrid })); } return (0, _vue.createCommentVNode)(); }; /** * 渲染表格 */ const renderTable = () => { const { proxyConfig } = props; const tableProps = computeTableProps.value; const proxyOpts = computeProxyOpts.value; const tableOns = Object.assign({}, tableCompEvents); const emptySlot = slots.empty; const loadingSlot = slots.loading; const rowDragIconSlot = slots.rowDragIcon || slots['row-drag-icon']; const columnDragIconSlot = slots.columnDragIcon || slots['column-drag-icon']; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { if (proxyOpts.sort) { tableOns.onSortChange = sortChangeEvent; } if (proxyOpts.filter) { tableOns.onFilterChange = filterChangeEvent; } } const slotObj = {}; if (emptySlot) { slotObj.empty = emptySlot; } if (loadingSlot) { slotObj.loading = loadingSlot; } if (rowDragIconSlot) { slotObj.rowDragIcon = rowDragIconSlot; } if (columnDragIconSlot) { slotObj.columnDragIcon = columnDragIconSlot; } return (0, _vue.h)('div', { class: 'vxe-grid--table-wrapper' }, [(0, _vue.h)(_table.default, Object.assign(Object.assign({ ref: refTable }, tableProps), tableOns), slotObj)]); }; /** * 渲染表格底部区域 */ const renderBottom = () => { if (slots.bottom) { return (0, _vue.h)('div', { ref: refBottomWrapper, key: 'bottom', class: 'vxe-grid--bottom-wrapper' }, slots.bottom({ $grid: $xeGrid })); } return (0, _vue.createCommentVNode)(); }; /** * 渲染分页 */ const renderPager = () => { const { proxyConfig, pagerConfig } = props; const proxyOpts = computeProxyOpts.value; const pagerOpts = computePagerOpts.value; if (pagerConfig && (0, _utils.isEnableConf)(pagerOpts) || slots.pager) { let slotVNs = []; if (slots.pager) { slotVNs = slots.pager({ $grid: $xeGrid }); } else { const pagerOptSlots = pagerOpts.slots; const pagerSlots = {}; let leftSlot; let rightSlot; if (pagerOptSlots) { leftSlot = getFuncSlot(pagerOptSlots, 'left'); rightSlot = getFuncSlot(pagerOptSlots, 'right'); if (leftSlot) { pagerSlots.left = leftSlot; } if (rightSlot) { pagerSlots.right = rightSlot; } } if (VxeUIPagerComponent) { slotVNs.push((0, _vue.h)(VxeUIPagerComponent, Object.assign(Object.assign(Object.assign({ ref: refPager }, pagerOpts), proxyConfig && (0, _utils.isEnableConf)(proxyOpts) ? reactData.tablePage : {}), { onPageChange: pageChangeEvent }), pagerSlots)); } } return (0, _vue.h)('div', { ref: refPagerWrapper, key: 'pager', class: 'vxe-grid--pager-wrapper' }, slotVNs); } return (0, _vue.createCommentVNode)(); }; const renderChildLayout = layoutKeys => { const childVNs = []; layoutKeys.forEach(key => { switch (key) { case 'Form': childVNs.push(renderForm()); break; case 'Toolbar': childVNs.push(renderToolbar()); break; case 'Top': childVNs.push(renderTop()); break; case 'Table': childVNs.push((0, _vue.h)('div', { key: 'table', class: 'vxe-grid--table-container' }, [renderTableLeft(), renderTable(), renderTableRight()])); break; case 'Bottom': childVNs.push(renderBottom()); break; case 'Pager': childVNs.push(renderPager()); break; default: (0, _log.errLog)('vxe.error.notProp', [`layouts -> ${key}`]); break; } }); return childVNs; }; const renderLayout = () => { const currLayoutConf = computeCurrLayoutConf.value; const { headKeys, bodyKeys, footKeys } = currLayoutConf; const asideLeftSlot = slots.asideLeft || slots['aside-left']; const asideRightSlot = slots.asideRight || slots['aside-right']; return [(0, _vue.h)('div', { class: 'vxe-grid--layout-header-wrapper' }, renderChildLayout(headKeys)), (0, _vue.h)('div', { class: 'vxe-grid--layout-body-wrapper' }, [asideLeftSlot ? (0, _vue.h)('div', { class: 'vxe-grid--layout-aside-left-wrapper' }, asideLeftSlot({})) : renderEmptyElement($xeGrid), (0, _vue.h)('div', { class: 'vxe-grid--layout-body-content-wrapper' }, renderChildLayout(bodyKeys)), asideRightSlot ? (0, _vue.h)('div', { class: 'vxe-grid--layout-aside-right-wrapper' }, asideRightSlot({})) : renderEmptyElement($xeGrid)]), (0, _vue.h)('div', { class: 'vxe-grid--layout-footer-wrapper' }, renderChildLayout(footKeys))]; }; const tableCompEvents = {}; _emits.default.forEach(name => { const type = _xeUtils.default.camelCase(`on-${name}`); tableCompEvents[type] = (...args) => emit(name, ...args); }); const initProxy = () => { const { proxyConfig, formConfig } = props; const { proxyInited } = reactData; const proxyOpts = computeProxyOpts.value; const formOpts = computeFormOpts.value; if (proxyConfig && (0, _utils.isEnableConf)(proxyOpts)) { if (formConfig && (0, _utils.isEnableConf)(formOpts) && proxyOpts.form && formOpts.items) { const fData = {}; formOpts.items.forEach(item => { const { field, itemRender } = item; if (field) { let itemValue = null; if (itemRender) { const { defaultValue } = itemRender; if (_xeUtils.default.isFunction(defaultValue)) { itemValue = defaultValue({ item }); } else if (!_xeUtils.default.isUndefined(defaultValue)) { itemValue = defaultValue; } } fData[field] = itemValue; } }); reactData.formData = fData; } if (!proxyInited) { reactData.proxyInited = true; if (proxyOpts.autoLoad !== false) { (0, _vue.nextTick)().then(() => gridMethods.commitProxy('_init')).then(rest => { gridMethods.dispatchEvent('proxy-query', Object.assign(Object.assign({}, rest), { isInited: true }), new Event('init')); }); } } } }; const handleGlobalKeydownEvent = evnt => { const zoomOpts = computeZoomOpts.value; const isEsc = globalEvents.hasKey(evnt, GLOBAL_EVENT_KEYS.ESCAPE); if (isEsc && reactData.isZMax && zoomOpts.escRestore !== false) { gridPrivateMethods.triggerZoomEvent(evnt); } }; const dispatchEvent = (type, params, evnt) => { emit(type, createEvent(evnt, { $grid: $xeGrid }, params)); }; const gridMethods = { dispatchEvent, /** * 提交指令,支持 code 或 button * @param {String/Object} code 字符串或对象 */ commitProxy(proxyTarget, ...args) { const { toolbarConfig, pagerConfig, editRules, validConfig } = props; const { tablePage } = reactData; const isActiveMsg = computeIsActiveMsg.value; const isRespMsg = computeIsRespMsg.value; const proxyOpts = computeProxyOpts.value; const pagerOpts = computePagerOpts.value; const toolbarOpts = computeToolbarOpts.value; const { beforeQuery, afterQuery, beforeDelete, afterDelete, beforeSave, afterSave, ajax = {} } = proxyOpts; const resConfigs = proxyOpts.response || proxyOpts.props || {}; const $xeTable = refTable.value; const formData = getFormData(); let button = null; let code = null; if (_xeUtils.default.isString(proxyTarget)) { const { buttons } = toolbarOpts; const matchObj = toolbarConfig && (0, _utils.isEnableConf)(toolbarOpts) && buttons ? _xeUtils.default.findTree(buttons, item => item.code === proxyTarget, { children: 'dropdowns' }) : null; button = matchObj ? matchObj.item : null; code = proxyTarget; } else { button = proxyTarget; code = button.code; } const btnParams = button ? button.params : null; switch (code) { case 'insert': return $xeTable.insert({}); case 'insert_edit': return $xeTable.insert({}).then(({ row }) => $xeTable.setEditRow(row)); // 已废弃 case 'insert_actived': return $xeTable.insert({}).then(({ row }) => $xeTable.setEditRow(row)); // 已废弃 case 'mark_cancel': triggerPendingEvent(code); break; case 'remove': return handleDeleteRow(code, 'vxe.grid.removeSelectRecord', () => $xeTable.removeCheckboxRow()); case 'import': $xeTable.importData(btnParams); break; case 'open_import': $xeTable.openImport(btnParams); break; case 'export': $xeTable.exportData(btnParams); break; case 'open_export': $xeTable.openExport(btnParams); break; case 'reset_custom': return $xeTable.resetCustom(true); case '_init': case 'reload': case 'query': { const ajaxMethods = ajax.query; const querySuccessMethods = ajax.querySuccess; const queryErrorMethods = ajax.queryError; if (ajaxMethods) { const isInited = code === '_init'; const isReload = code === 'reload'; let sortList = []; let filterList = []; let pageParams = {}; if (pagerConfig) { if (isInited || isReload) { tablePage.currentPage = 1; } if ((0, _utils.isEnableConf)(pagerOpts)) { pageParams = Object.assign({}, tablePage); } } if (isInited) { let defaultSort = null; if ($xeTable) { const { computeSortOpts } = $xeTable.getComputeMaps(); const sortOpts = computeSortOpts.value; defaultSort = sortOpts.defaultSort; } // 如果使用默认排序 if (defaultSort) { if (!_xeUtils.default.isArray(defaultSort)) { defaultSort = [defaultSort]; } sortList = defaultSort.map(item => { return { field: item.field, property: item.field, order: item.order }; }); } if ($xeTable) { filterList = $xeTable.getCheckedFilters(); } } else { if ($xeTable) { if (isReload) { $xeTable.clearAll(); } else { sortList = $xeTable.getSortColumns(); filterList = $xeTable.getCheckedFilters(); } } } const commitParams = { code, button, isInited, isReload, $grid: $xeGrid, page: pageParams, sort: sortList.length ? sortList[0] : {}, sorts: sortList, filters: filterList, form: formData, options: ajaxMethods }; reactData.sortData = sortList; reactData.filterData = filterList; reactData.tableLoading = true; return Promise.resolve((beforeQuery || ajaxMethods)(commitParams, ...args)).then(rest => { reactData.tableLoading = false; if (rest) { if (pagerConfig && (0, _utils.isEnableConf)(pagerOpts)) { const totalProp = resConfigs.total; const total = (_xeUtils.default.isFunction(totalProp) ? totalProp({ data: rest, $grid: $xeGrid }) : _xeUtils.default.get(rest, totalProp || 'page.total')) || 0; tablePage.total = _xeUtils.default.toNumber(total); const resultProp = resConfigs.result; reactData.tableData = (_xeUtils.default.isFunction(resultProp) ? resultProp({ data: rest, $grid: $xeGrid }) : _xeUtils.default.get(rest, resultProp || 'result')) || []; // 检验当前页码,不能超出当前最大页数 const pageCount = Math.max(Math.ceil(total / tablePage.pageSize), 1); if (tablePage.currentPage > pageCount) { tablePage.currentPage = pageCount; } } else { const listProp = resConfigs.list; reactData.tableData = (listProp ? _xeUtils.default.isFunction(listProp) ? listProp({ data: rest, $grid: $xeGrid }) : _xeUtils.default.get(rest, listProp) : rest) || []; } } else { reactData.tableData = []; } if (afterQuery) { afterQuery(commitParams, ...args); } if (querySuccessMethods) { querySuccessMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: true }; }).catch(rest => { reactData.tableLoading = false; if (queryErrorMethods) { queryErrorMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: false }; }); } else { if (process.env.NODE_ENV === 'development') { (0, _log.errLog)('vxe.error.notFunc', ['proxy-config.ajax.query']); } } break; } case 'delete': { const ajaxMethods = ajax.delete; const deleteSuccessMethods = ajax.deleteSuccess; const deleteErrorMethods = ajax.deleteError; if (ajaxMethods) { const selectRecords = gridExtendTableMethods.getCheckboxRecords(); const removeRecords = selectRecords.filter(row => !$xeTable.isInsertByRow(row)); const body = { removeRecords }; const commitParams = { $grid: $xeGrid, code, button, body, form: formData, options: ajaxMethods }; if (selectRecords.length) { return handleDeleteRow(code, 'vxe.grid.deleteSelectRecord', () => { if (!removeRecords.length) { return $xeTable.remove(selectRecords); } reactData.tableLoading = true; return Promise.resolve((beforeDelete || ajaxMethods)(commitParams, ...args)).then(rest => { reactData.tableLoading = false; $xeTable.setPendingRow(removeRecords, false); if (isRespMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ content: getRespMsg(rest, 'vxe.grid.delSuccess'), status: 'success' }); } } if (afterDelete) { afterDelete(commitParams, ...args); } else { gridMethods.commitProxy('query'); } if (deleteSuccessMethods) { deleteSuccessMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: true }; }).catch(rest => { reactData.tableLoading = false; if (isRespMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: code, content: getRespMsg(rest, 'vxe.grid.operError'), status: 'error' }); } } if (deleteErrorMethods) { deleteErrorMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: false }; }); }); } else { if (isActiveMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.selectOneRecord'), status: 'warning' }); } } } } else { if (process.env.NODE_ENV === 'development') { (0, _log.errLog)('vxe.error.notFunc', ['proxy-config.ajax.delete']); } } break; } case 'save': { const ajaxMethods = ajax.save; const saveSuccessMethods = ajax.saveSuccess; const saveErrorMethods = ajax.saveError; if (ajaxMethods) { const body = $xeTable.getRecordset(); const { insertRecords, removeRecords, updateRecords, pendingRecords } = body; const commitParams = { $grid: $xeGrid, code, button, body, form: formData, options: ajaxMethods }; // 排除掉新增且标记为删除的数据 if (insertRecords.length) { body.pendingRecords = pendingRecords.filter(row => $xeTable.findRowIndexOf(insertRecords, row) === -1); } // 排除已标记为删除的数据 if (pendingRecords.length) { body.insertRecords = insertRecords.filter(row => $xeTable.findRowIndexOf(pendingRecords, row) === -1); } let restPromise = Promise.resolve(); if (editRules) { // 只校验新增和修改的数据 restPromise = $xeTable[validConfig && validConfig.msgMode === 'full' ? 'fullValidate' : 'validate'](body.insertRecords.concat(updateRecords)); } return restPromise.then(errMap => { if (errMap) { // 如果校验不通过 return; } if (body.insertRecords.length || removeRecords.length || updateRecords.length || body.pendingRecords.length) { reactData.tableLoading = true; return Promise.resolve((beforeSave || ajaxMethods)(commitParams, ...args)).then(rest => { reactData.tableLoading = false; $xeTable.clearPendingRow(); if (isRespMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ content: getRespMsg(rest, 'vxe.grid.saveSuccess'), status: 'success' }); } } if (afterSave) { afterSave(commitParams, ...args); } else { gridMethods.commitProxy('query'); } if (saveSuccessMethods) { saveSuccessMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: true }; }).catch(rest => { reactData.tableLoading = false; if (isRespMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: code, content: getRespMsg(rest, 'vxe.grid.operError'), status: 'error' }); } } if (saveErrorMethods) { saveErrorMethods(Object.assign(Object.assign({}, commitParams), { response: rest })); } return { status: false }; }); } else { if (isActiveMsg) { if (_ui.VxeUI.modal) { _ui.VxeUI.modal.message({ id: code, content: getI18n('vxe.grid.dataUnchanged'), status: 'info' }); } } } }); } else { if (process.env.NODE_ENV === 'development') { (0, _log.errLog)('vxe.error.notFunc', ['proxy-config.ajax.save']); } } break; } default: { const gCommandOpts = commands.get(code); if (gCommandOpts) { const tCommandMethod = gCommandOpts.tableCommandMethod || gCommandOpts.commandMethod; if (tCommandMethod) { tCommandMethod({ code, button, $grid: $xeGrid, $table: $xeTable }, ...args); } else { if (process.env.NODE_ENV === 'development') { (0, _log.errLog)('vxe.error.notCommands', [code]); } } } } } return (0, _vue.nextTick)(); }, zoom() { if (reactData.isZMax) { return gridMethods.revert(); } return gridMethods.maximize(); }, isMaximized() { return reactData.isZMax; }, maximize() { return handleZoom(true); }, revert() { return handleZoom(); }, getFormData, getFormItems(itemIndex) { const formOpts = computeFormOpts.value; const { formConfig } = props; const { items } = formOpts; const itemList = []; _xeUtils.default.eachTree(formConfig && (0, _utils.isEnableConf)(formOpts) && items ? items : [], item => { itemList.push(item); }, { children: 'children' }); return _xeUtils.default.isUndefined(itemIndex) ? itemList : itemList[itemIndex]; }, getProxyInfo() { const $xeTable = refTable.value; if (props.proxyConfig) { const { sortData } = reactData; return { data: reactData.tableData, filter: reactData.filterData, form: getFormData(), sort: sortData.length ? sortData[0] : {}, sorts: sortData, pager: reactData.tablePage, pendingRecords: $xeTable ? $xeTable.getPendingRecords() : [] }; } return null; } // setProxyInfo (options) { // if (props.proxyConfig && options) { // const { pager, form } = options // const proxyOpts = computeProxyOpts.value // if (pager) { // if (pager.currentPage) { // reactData.tablePage.currentPage = Number(pager.currentPage) // } // if (pager.pageSize) { // reactData.tablePage.pageSize = Number(pager.pageSize) // } // } // if (proxyOpts.form && form) { // Object.assign(reactData.formData, form) // } // } // return nextTick() // } }; // 检查插槽 if (process.env.NODE_ENV === 'development') { gridMethods.loadColumn = columns => { const $xeTable = refTable.value; _xeUtils.default.eachTree(columns, column => { if (column.slots) { _xeUtils.default.each(column.slots, func => { if (!_xeUtils.default.isFunction(func)) { if (!slots[func]) { (0, _log.errLog)('vxe.error.notSlot', [func]); } } }); } }); if ($xeTable) { return $xeTable.loadColumn(columns); } return (0, _vue.nextTick)(); }; gridMethods.reloadColumn = columns => { gridExtendTableMethods.clearAll(); return gridMethods.loa