1
0
mirror of synced 2025-11-06 11:20:40 +08:00

支持行标记为删除

This commit is contained in:
xuliangzhan
2023-12-25 00:43:38 +08:00
parent 153b2b91da
commit 685cffe8a3
16 changed files with 249 additions and 136 deletions

View File

@@ -13,6 +13,7 @@
<vxe-button type="text" @click="insertEvent($refs.xTable.getData(300))">插入到 300 </vxe-button>
</template>
</vxe-button>
<vxe-button @click="validEvent">快速校验</vxe-button>
<vxe-button>
<template #default>删除操作</template>
<template #dropdowns>
@@ -38,8 +39,10 @@
:export-config="{}"
:loading="demo1.loading"
:checkbox-config="{checkField: 'checked'}"
:edit-rules="validRules"
:edit-config="{trigger: 'click', mode: 'row', showStatus: true}"
:scroll-y="{enabled: true}">
:scroll-x="{enabled: true, gt: 0}"
:scroll-y="{enabled: true, gt: 0}">
<vxe-column type="checkbox" width="60"></vxe-column>
<vxe-column type="seq" width="100"></vxe-column>
<vxe-column field="name" title="Name" sortable width="200" :edit-render="{name: 'input'}"></vxe-column>
@@ -59,6 +62,13 @@
<vxe-column field="attr7" title="Attr7" width="200"></vxe-column>
<vxe-column field="attr8" title="Attr8" width="200"></vxe-column>
<vxe-column field="attr9" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr10" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr11" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr12" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr13" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr14" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr15" title="Attr9" width="200"></vxe-column>
<vxe-column field="attr16" title="Attr9" width="200"></vxe-column>
<vxe-column field="createTime" title="CreateTime" width="200"></vxe-column>
</vxe-table>
@@ -84,6 +94,16 @@ export default defineComponent({
const xTable = ref({} as VxeTableInstance)
const validRules = reactive({
name: [
{ required: true, message: 'app.body.valid.rName' },
{ min: 3, max: 50, message: '名称长度在 3 到 50 个字符' }
],
sex: [
{ required: true, message: '性别必须填写' }
]
})
const mockList = (size: number) => {
const list: any[] = []
for (let index = 0; index < size; index++) {
@@ -117,6 +137,16 @@ export default defineComponent({
})
}
const validEvent = async () => {
const $table = xTable.value
const errMap = await $table.validate()
if (errMap) {
VXETable.modal.message({ status: 'error', message: '校验不通过!' })
} else {
VXETable.modal.message({ status: 'success', message: '校验成功!' })
}
}
const insertEvent = (row: any) => {
const $table = xTable.value
const record = {
@@ -150,7 +180,9 @@ export default defineComponent({
return {
xTable,
demo1,
validRules,
findList,
validEvent,
insertEvent,
getInsertEvent,
getRemoveEvent,

View File

@@ -243,7 +243,7 @@
"proxy-config",
"zoom-config"
],
"description": "高级表格"
"description": "配置式表格"
},
"vxe-toolbar": {
"attributes": [

View File

@@ -1,6 +1,6 @@
{
"name": "vxe-table",
"version": "4.5.16",
"version": "4.5.17-beta.0",
"description": "一个基于 vue 的 PC 端表单/表格组件支持增删改查、虚拟列表、虚拟树、懒加载、快捷菜单、数据校验、树形结构、打印导出、表单渲染、数据分页、弹窗、自定义模板、渲染器、JSON 配置式...",
"scripts": {
"update": "npm install --legacy-peer-deps",

View File

@@ -424,13 +424,14 @@ const editHook: VxeGlobalHooksHandles.HookOptions = {
})
},
/**
* 获取表格数据集,包含新增、删除、修改
* 获取表格数据集,包含新增、删除、修改、标记
*/
getRecordset () {
return {
insertRecords: editMethods.getInsertRecords(),
removeRecords: editMethods.getRemoveRecords(),
updateRecords: editMethods.getUpdateRecords()
updateRecords: editMethods.getUpdateRecords(),
pendingRecords: $xetable.getPendingRecords()
}
},
/**
@@ -486,7 +487,7 @@ const editHook: VxeGlobalHooksHandles.HookOptions = {
const { afterFullData } = internalData
const el = refElem.value
const { args, row } = editStore.actived
if (args && $xetable.findRowIndexOf(afterFullData, row) > -1 && el.querySelectorAll('.vxe-body--column.col--actived').length) {
if (args && $xetable.findRowIndexOf(afterFullData, row) > -1 && el.querySelectorAll('.vxe-body--column.col--active').length) {
return Object.assign({}, args)
}
return null
@@ -654,10 +655,10 @@ const editHook: VxeGlobalHooksHandles.HookOptions = {
const cell = (params.cell || $xetable.getCell(row, column))
const beforeEditMethod = editOpts.beforeEditMethod || editOpts.activeMethod
params.cell = cell
if (isEnableConf(editConfig) && isEnableConf(editRender) && cell) {
if (isEnableConf(editConfig) && isEnableConf(editRender) && !$xetable.hasPendingByRow(row) && cell) {
if (actived.row !== row || (mode === 'cell' ? actived.column !== column : false)) {
// 判断是否禁用编辑
let type: 'edit-disabled' | 'edit-actived' = 'edit-disabled'
let type: 'edit-disabled' | 'edit-activated' = 'edit-disabled'
if (!beforeEditMethod || beforeEditMethod({ ...params, $table: $xetable })) {
if (mouseConfig) {
editMethods.clearSelected()
@@ -670,7 +671,7 @@ const editHook: VxeGlobalHooksHandles.HookOptions = {
if (actived.column) {
editMethods.clearEdit(evnt)
}
type = 'edit-actived'
type = 'edit-activated'
column.renderHeight = cell.offsetHeight
actived.args = params
actived.row = row
@@ -692,6 +693,18 @@ const editHook: VxeGlobalHooksHandles.HookOptions = {
columnIndex: $xetable.getColumnIndex(column),
$columnIndex: $xetable.getVMColumnIndex(column)
}, evnt)
// v4已废弃
if (type === 'edit-activated') {
$xetable.dispatchEvent('edit-actived', {
row,
rowIndex: $xetable.getRowIndex(row),
$rowIndex: $xetable.getVMRowIndex(row),
column,
columnIndex: $xetable.getColumnIndex(column),
$columnIndex: $xetable.getVMColumnIndex(column)
}, evnt)
}
} else {
const { column: oldColumn } = actived
if (mouseConfig) {

View File

@@ -15,7 +15,7 @@ import { TableMethods, VxeGridConstructor, VxeGridEmits, GridReactData, VxeGridP
const tableComponentPropKeys = Object.keys(tableComponentProps as any)
const tableComponentMethodKeys: (keyof TableMethods)[] = ['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', 'setColumnFixed', 'clearColumnFixed', 'setColumnWidth', 'getColumnWidth', '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', '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', 'openTooltip', 'focus', 'blur', 'connect']
const tableComponentMethodKeys: (keyof TableMethods)[] = ['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', 'setColumnFixed', 'clearColumnFixed', 'setColumnWidth', 'getColumnWidth', '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', 'setPendingRow', 'getPendingRecords', 'clearPendingRow', 'sort', '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', 'openTooltip', 'focus', 'blur', 'connect']
const gridComponentEmits: VxeGridEmits = [
...tableComponentEmits,
@@ -60,7 +60,6 @@ export default defineComponent({
proxyInited: false,
isZMax: false,
tableData: [],
pendingRecords: [],
filterData: [],
formData: {},
sortData: [],
@@ -174,28 +173,6 @@ export default defineComponent({
let gridMethods = {} as GridMethods
const handleRowClassName = (params: any) => {
const { pendingRecords } = reactData
const rowClassName = props.rowClassName
const clss = []
if (pendingRecords.some((item) => item === params.row)) {
clss.push('row--pending')
}
clss.push(rowClassName ? (XEUtils.isFunction(rowClassName) ? rowClassName(params) : rowClassName) : '')
return clss
}
const handleBeforeEditMethod = (params: any) => {
const { editConfig } = props
const { pendingRecords } = reactData
const $xetable = refTable.value
const beforeEditMethod = editConfig ? (editConfig.beforeEditMethod || editConfig.activeMethod) : null
if ($xetable.findRowIndexOf(pendingRecords, params.row) === -1) {
return !beforeEditMethod || beforeEditMethod({ ...params, $grid: $xegrid })
}
return false
}
const computeTableProps = computed(() => {
const { seqConfig, pagerConfig, loading, editConfig, proxyConfig } = props
const { isZMax, tableLoading, tablePage, tableData } = reactData
@@ -213,13 +190,12 @@ export default defineComponent({
if (proxyConfig && isEnableConf(proxyOpts)) {
tableProps.loading = loading || tableLoading
tableProps.data = tableData
tableProps.rowClassName = handleRowClassName
if (pagerConfig && proxyOpts.seq && isEnableConf(pagerOpts)) {
tableProps.seqConfig = Object.assign({}, seqConfig, { startIndex: (tablePage.currentPage - 1) * tablePage.pageSize })
}
}
if (editConfig) {
tableProps.editConfig = Object.assign({}, editConfig, { beforeEditMethod: handleBeforeEditMethod })
tableProps.editConfig = Object.assign({}, editConfig)
}
return tableProps
})
@@ -253,25 +229,11 @@ export default defineComponent({
}
const triggerPendingEvent = (code: string) => {
const { pendingRecords } = reactData
const isMsg = computeIsMsg.value
const $xetable = refTable.value
const selectRecords = $xetable.getCheckboxRecords()
if (selectRecords.length) {
const plus: any[] = []
const minus: any[] = []
selectRecords.forEach((data) => {
if (pendingRecords.some((item) => data === item)) {
minus.push(data)
} else {
plus.push(data)
}
})
if (minus.length) {
reactData.pendingRecords = pendingRecords.filter((item) => $xetable.findRowIndexOf(minus, item) === -1).concat(plus)
} else if (plus.length) {
reactData.pendingRecords = pendingRecords.concat(plus)
}
$xetable.togglePendingRow(selectRecords)
gridExtendTableMethods.clearCheckboxRow()
} else {
if (isMsg) {
@@ -726,8 +688,14 @@ export default defineComponent({
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
@@ -785,7 +753,6 @@ export default defineComponent({
filterList = $xetable.getCheckedFilters()
} else {
if (isReload) {
reactData.pendingRecords = []
$xetable.clearAll()
} else {
sortList = $xetable.getSortColumns()
@@ -860,7 +827,7 @@ export default defineComponent({
return Promise.resolve((beforeDelete || ajaxMethods)(...applyArgs))
.then(rest => {
reactData.tableLoading = false
reactData.pendingRecords = reactData.pendingRecords.filter((row) => $xetable.findRowIndexOf(removeRecords, row) === -1)
$xetable.setPendingRow(removeRecords, false)
if (isMsg) {
// 检测弹窗模块
if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
@@ -911,7 +878,7 @@ export default defineComponent({
case 'save': {
const ajaxMethods = ajax.save
if (ajaxMethods) {
const body = Object.assign({ pendingRecords: reactData.pendingRecords }, $xetable.getRecordset())
const body = $xetable.getRecordset()
const { insertRecords, removeRecords, updateRecords, pendingRecords } = body
const commitParams = { $grid: $xegrid, code, button, body, form: formData, options: ajaxMethods }
const applyArgs = [commitParams].concat(args)
@@ -938,7 +905,7 @@ export default defineComponent({
return Promise.resolve((beforeSave || ajaxMethods)(...applyArgs))
.then(rest => {
reactData.tableLoading = false
reactData.pendingRecords = []
$xetable.clearPendingRow()
if (isMsg) {
// 检测弹窗模块
if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') {
@@ -1027,10 +994,8 @@ export default defineComponent({
}, { children: 'children' })
return XEUtils.isUndefined(itemIndex) ? itemList : itemList[itemIndex]
},
getPendingRecords () {
return reactData.pendingRecords
},
getProxyInfo () {
const $xetable = refTable.value
if (props.proxyConfig) {
const { sortData } = reactData
return {
@@ -1040,7 +1005,7 @@ export default defineComponent({
sort: sortData.length ? sortData[0] : {},
sorts: sortData,
pager: reactData.tablePage,
pendingRecords: reactData.pendingRecords
pendingRecords: $xetable ? $xetable.getPendingRecords() : []
}
}
return null

View File

@@ -275,13 +275,13 @@ export default defineComponent({
if (showValidTip && errorValidItem) {
tdVNs.push(
h('div', {
class: 'vxe-cell--valid',
class: 'vxe-cell--valid-error-hint',
style: errorValidItem.rule && errorValidItem.rule.maxWidth ? {
width: `${errorValidItem.rule.maxWidth}px`
} : null
}, [
h('span', {
class: 'vxe-cell--valid-msg'
class: 'vxe-cell--valid-error-msg'
}, errorValidItem.content)
])
)
@@ -301,7 +301,7 @@ export default defineComponent({
'col--ellipsis': hasEllipsis,
'fixed--hidden': fixedHiddenColumn,
'col--dirty': isDirty,
'col--actived': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
'col--active': editConfig && isEdit && (actived.row === row && (actived.column === column || editOpts.mode === 'row')),
'col--valid-error': !!errorValidItem,
'col--current': currentColumn === column
},
@@ -320,7 +320,7 @@ export default defineComponent({
const renderRows = (fixedType: any, tableData: any, tableColumn: any) => {
const { stripe, rowKey, highlightHoverRow, rowClassName, rowStyle, showOverflow: allColumnOverflow, editConfig, treeConfig } = tableProps
const { hasFixedColumn, treeExpandedMaps, scrollYLoad, rowExpandedMaps, expandColumn, selectRadioRow } = tableReactData
const { hasFixedColumn, treeExpandedMaps, scrollYLoad, rowExpandedMaps, expandColumn, selectRadioRow, pendingRowMaps, pendingRowList } = tableReactData
const { fullAllDataRowIdData } = tableInternalData
const checkboxOpts = computeCheckboxOpts.value
const radioOpts = computeRadioOpts.value
@@ -387,7 +387,8 @@ export default defineComponent({
'is--expand-tree': isExpandTree,
'row--new': isNewRow && (editOpts.showStatus || editOpts.showInsertStatus),
'row--radio': radioOpts.highlight && $xetable.eqRow(selectRadioRow, row),
'row--checked': checkboxOpts.highlight && $xetable.isCheckedByCheckboxRow(row)
'row--checked': checkboxOpts.highlight && $xetable.isCheckedByCheckboxRow(row),
'row--pending': pendingRowList.length && !!pendingRowMaps[rowid]
},
getPropClass(rowClassName, params)
],

View File

@@ -39,7 +39,10 @@ export default [
'toggle-tree-expand',
'menu-click',
'edit-closed',
'edit-actived',
'edit-actived', // 废弃
'edit-activated',
'edit-disabled',
'valid-error',
'scroll',

View File

@@ -109,6 +109,10 @@ export default defineComponent({
upDataFlag: 0,
// 刷新列标识,当列的特定属性被改变时,触发表格刷新列
reColumnFlag: 0,
// 已标记的对象集
pendingRowMaps: {},
// 已标记的行
pendingRowList: [],
// 初始化标识
initStore: {
filter: false,
@@ -3689,6 +3693,75 @@ export default defineComponent({
reactData.currentColumn = null
return nextTick()
},
setPendingRow (rows: any | any[], status: boolean) {
const pendingMaps = { ...reactData.pendingRowMaps }
const pendingList = [...reactData.pendingRowList]
if (rows && !XEUtils.isArray(rows)) {
rows = [rows]
}
if (status) {
rows.forEach((row: any) => {
const rowid = getRowid($xetable, row)
if (rowid && !pendingMaps[rowid]) {
pendingList.push(row)
pendingMaps[rowid] = row
}
})
} else {
rows.forEach((row: any) => {
const rowid = getRowid($xetable, row)
if (rowid && pendingMaps[rowid]) {
const pendingIndex = $xetable.findRowIndexOf(pendingList, row)
if (pendingIndex > -1) {
pendingList.splice(pendingIndex, 1)
}
delete pendingMaps[rowid]
}
})
}
reactData.pendingRowMaps = pendingMaps
reactData.pendingRowList = pendingList
return nextTick()
},
togglePendingRow (rows: any | any[]) {
const pendingMaps = { ...reactData.pendingRowMaps }
const pendingList = [...reactData.pendingRowList]
if (rows && !XEUtils.isArray(rows)) {
rows = [rows]
}
rows.forEach((row: any) => {
const rowid = getRowid($xetable, row)
if (rowid) {
if (pendingMaps[rowid]) {
const pendingIndex = $xetable.findRowIndexOf(pendingList, row)
if (pendingIndex > -1) {
pendingList.splice(pendingIndex, 1)
}
delete pendingMaps[rowid]
} else {
pendingList.push(row)
pendingMaps[rowid] = row
}
}
})
reactData.pendingRowMaps = pendingMaps
reactData.pendingRowList = pendingList
return nextTick()
},
hasPendingByRow (row) {
const { pendingRowMaps } = reactData
const rowid = getRowid($xetable, row)
return !!pendingRowMaps[rowid]
},
getPendingRecords () {
const { pendingRowList } = reactData
return pendingRowList.slice(0)
},
clearPendingRow () {
reactData.pendingRowMaps = {}
reactData.pendingRowList = []
return nextTick()
},
sort (sortConfs: any, sortOrder?: VxeTablePropTypes.SortOrder) {
const sortOpts = computeSortOpts.value
const { multiple, remote, orders } = sortOpts
@@ -4246,7 +4319,7 @@ export default defineComponent({
return nextTick()
},
/**
* 更新列状态
* 更新列状态 updateStatus({ row, column }, cellValue)
* 如果组件值 v-model 发生 change 时,调用改函数用于更新某一列编辑状态
* 如果单元格配置了校验规则,则会进行校验
*/
@@ -6697,6 +6770,13 @@ export default defineComponent({
isArrow: false,
enterable: false
}) : createCommentVNode(),
/**
* 工具提示
*/
hasUseTooltip ? h(resolveComponent('vxe-tooltip') as ComponentOptions, {
ref: refTooltip,
...tipConfig
}) : createCommentVNode(),
/**
* 校验提示
*/
@@ -6706,13 +6786,6 @@ export default defineComponent({
'old-cell-valid': editRules && GlobalConfig.cellVaildMode === 'obsolete'
}, 'vxe-table--valid-error'],
...(validOpts.message === 'tooltip' || tableData.length === 1 ? validTipOpts : {})
}) : createCommentVNode(),
/**
* 工具提示
*/
hasUseTooltip ? h(resolveComponent('vxe-tooltip') as ComponentOptions, {
ref: refTooltip,
...tipConfig
}) : createCommentVNode()
])
}

View File

@@ -292,6 +292,7 @@ export function clearTableDefaultStatus ($xetable: VxeTableConstructor & VxeTabl
$xetable.clearRowExpand()
$xetable.clearTreeExpand()
$xetable.clearTreeExpandReserve()
$xetable.clearPendingRow()
if ($xetable.clearFilter) {
$xetable.clearFilter()
}

View File

@@ -336,7 +336,7 @@ export default defineComponent({
'is--enterable': enterable,
'is--visible': visible,
'is--arrow': isArrow,
'is--actived': tipActive
'is--active': tipActive
}],
style: tipStore.style,
...ons

View File

@@ -108,7 +108,7 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
const beginValidate = (rows: any, cb: any, isFull?: boolean): Promise<any> => {
const validRest: any = {}
const { editRules, treeConfig } = props
const { afterFullData } = internalData
const { afterFullData, visibleColumn } = internalData
const treeOpts = computeTreeOpts.value
const childrenField = treeOpts.children || treeOpts.childrenField
const validOpts = computeValidOpts.value
@@ -223,17 +223,16 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
* 将表格滚动到可视区
* 由于提示信息至少需要占一行,定位向上偏移一行
*/
const row = firstErrParams.row
const rowIndex = afterFullData.indexOf(row)
const locatRow = rowIndex > 0 ? afterFullData[rowIndex - 1] : row
if (validOpts.autoPos === false) {
finish()
} else {
if (treeConfig) {
$xetable.scrollToTreeRow(locatRow).then(posAndFinish)
} else {
$xetable.scrollToRow(locatRow).then(posAndFinish)
}
const row = firstErrParams.row
const column = firstErrParams.column
const rowIndex = afterFullData.indexOf(row)
const columnIndex = visibleColumn.indexOf(column)
const locatRow = rowIndex > 0 ? afterFullData[rowIndex - 1] : row
const locatColumn = columnIndex > 0 ? visibleColumn[rowIndex - 1] : column
$xetable.scrollToRow(locatRow, locatColumn).then(posAndFinish)
}
})
})
@@ -493,33 +492,34 @@ const validatorHook: VxeGlobalHooksHandles.HookOptions = {
showValidTooltip (params) {
const { height } = props
const { tableData, validStore, validErrorMaps } = reactData
const { rule, row, column, cell } = params
const validOpts = computeValidOpts.value
const validTip = refValidTooltip.value
const content = rule.content
validStore.visible = true
if (validOpts.msgMode === 'single') {
reactData.validErrorMaps = {
[`${getRowid($xetable, params.row)}:${params.column.id}`]: {
column: params.column,
row: params.row,
rule: params.rule,
content: params.rule.content
[`${getRowid($xetable, row)}:${column.id}`]: {
column,
row,
rule,
content
}
}
} else {
reactData.validErrorMaps = Object.assign({}, validErrorMaps, {
[`${getRowid($xetable, params.row)}:${params.column.id}`]: {
column: params.column,
row: params.row,
rule: params.rule,
content: params.rule.content
[`${getRowid($xetable, row)}:${column.id}`]: {
column,
row,
rule,
content
}
})
}
$xetable.dispatchEvent('valid-error', params, null)
if (validTip) {
const { cell } = params
if (validTip && (validOpts.message === 'tooltip' || (validOpts.message === 'default' && !height && tableData.length < 2))) {
return validTip.open(cell, params.rule.content)
return validTip.open(cell, content)
}
}
return nextTick()

View File

@@ -29,26 +29,6 @@
padding: 0.5em 1em;
background-color: var(--vxe-grid-maximize-background-color);
}
.vxe-body--row {
&.row--pending {
color: var(--vxe-table-validate-error-color);
text-decoration: line-through;
cursor: no-drop;
.vxe-body--column {
position: relative;
&:after {
content: "";
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 0;
border-bottom: 1px solid var(--vxe-table-validate-error-color);
z-index: 1;
}
}
}
}
.vxe-grid--form-wrapper,
.vxe-grid--top-wrapper,
.vxe-grid--bottom-wrapper {

View File

@@ -1067,7 +1067,7 @@
.vxe-footer--column {
&.col--ellipsis {
@extend %DefaultColumnHeight;
&:not(.col--actived) {
&:not(.col--active) {
& > .vxe-cell {
@extend %TextEllipsis;
}
@@ -1173,12 +1173,12 @@
/*校验不通过*/
.vxe-body--column {
&.col--actived,
&.col--active,
&.col--selected {
position: relative;
}
&.col--valid-error {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
width: 100%;
position: absolute;
left: 50%;
@@ -1186,11 +1186,10 @@
line-height: 1.2em;
transform: translateX(-50%);
text-align: left;
pointer-events: none;
z-index: 4;
padding-left: var(--vxe-table-cell-padding-left);
padding-right: var(--vxe-table-cell-padding-right);
.vxe-cell--valid-msg {
.vxe-cell--valid-error-msg {
display: inline-block;
border-radius: var(--vxe-border-radius);
color: var(--vxe-table-validate-error-color);
@@ -1214,11 +1213,11 @@
&.vaild-msg--single {
.vxe-body--row {
&:last-child {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
bottom: calc(100%);
}
&:first-child {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
bottom: auto;
}
}
@@ -1228,7 +1227,7 @@
&.vaild-msg--full {
.vxe-body--row {
&:last-child {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
top: calc(100% - 1.3em);
}
}
@@ -1238,7 +1237,7 @@
&.old-cell-valid {
.vxe-body--column {
&.col--valid-error {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
width: 320px;
position: absolute;
bottom: calc(100% + 4px);
@@ -1247,7 +1246,7 @@
text-align: center;
pointer-events: none;
z-index: 4;
.vxe-cell--valid-msg {
.vxe-cell--valid-error-msg {
display: inline-block;
border-radius: $vxe-border-radius;
padding: 8px 12px;
@@ -1260,7 +1259,7 @@
}
.vxe-body--row {
&:first-child {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
bottom: auto;
top: calc(100% + 4px);
}
@@ -1268,7 +1267,7 @@
}
.vxe-body--column {
&:first-child {
.vxe-cell--valid {
.vxe-cell--valid-error-hint {
left: 10px;
transform: translateX(0);
text-align: left;
@@ -1277,6 +1276,28 @@
}
}
/*单元格标记删除状态*/
.vxe-body--row {
&.row--pending {
color: var(--vxe-table-validate-error-color);
text-decoration: line-through;
cursor: no-drop;
.vxe-body--column {
position: relative;
&:after {
content: "";
position: absolute;
top: 50%;
left: 0;
width: 100%;
height: 0;
border-bottom: 1px solid var(--vxe-table-validate-error-color);
z-index: 1;
}
}
}
}
/*单元格编辑状态*/
.vxe-body--row {
&.row--new {
@@ -1315,7 +1336,7 @@
&.vxe-editable {
&.cell--highlight {
.vxe-body--column {
&.col--actived {
&.col--active {
box-shadow: inset 0px 0px 0px 2px var(--vxe-primary-color);
&.col--valid-error {
box-shadow: inset 0px 0px 0px 2px var(--vxe-table-validate-error-color);
@@ -1347,7 +1368,7 @@
}
.vxe-body--column {
padding: 0;
&.col--actived {
&.col--active {
padding: 0;
}
}

1
types/edit.d.ts vendored
View File

@@ -61,6 +61,7 @@ export interface TableEditMethods<D = VxeTableDataRow> {
insertRecords: D[]
removeRecords: D[]
updateRecords: D[]
pendingRecords: D[]
}
/**
* 用于 edit-config获取新增的临时数据

9
types/grid.d.ts vendored
View File

@@ -9,12 +9,12 @@ import { VxeTableDataRow, VxeTableDefines, VxeTableEmits, VxeTableConstructor, V
/* eslint-disable no-use-before-define */
/**
* 组件 - 高级表格
* 组件 - 配置式表格
* @example import { VxeGrid } from 'vxe-table'
*/
export const VxeGrid: VXEComponent<VxeGridProps<any>, VxeGridEventProps<any>, VxeGridSlots<any>>
/**
* 组件 - 高级表格
* 组件 - 配置式表格
*/
export const Grid: typeof VxeGrid
@@ -54,7 +54,6 @@ export interface GridReactData<D = VxeTableDataRow> {
proxyInited: boolean
isZMax: boolean
tableData: D[]
pendingRecords: D[]
filterData: VxeTableDefines.FilterCheckedParams<D>[]
formData: any
sortData: VxeTableDefines.SortCheckedParams<D>[]
@@ -98,10 +97,6 @@ export interface GridPublicMethods<D = VxeTableDataRow> {
*/
getFormItems(): VxeFormItemProps[]
getFormItems(itemIndex?: number): VxeFormItemProps
/**
* 获取已标记删除的数据
*/
getPendingRecords(): D[]
/**
* 切换表格最大化/还原
*/

30
types/table.d.ts vendored
View File

@@ -453,6 +453,27 @@ export interface TablePublicMethods<DT = VxeTableDataRow> {
* @param row 指定行
*/
setRadioRow(row: any): Promise<any>
/**
* 将指定行设置为取消/标记待删除状态
*/
setPendingRow(rows: any | any[], status: boolean): Promise<any>
/**
* 切换指定行的取消/标记待删除状态
*/
togglePendingRow(rows: any | any[]): Promise<any>
/**
* 获取待删除状态的数据
*/
getPendingRecords(): DT[]
/**
* 判断行是否为待删除状态
* @param row 指定行
*/
hasPendingByRow(row: any): boolean
/**
* 清除所有标记状态
*/
clearPendingRow(): Promise<any>
/**
* 手动清除临时合并的单元格
*/
@@ -856,6 +877,10 @@ export interface TableReactData<D = VxeTableDataRow> {
upDataFlag: number
// 刷新列标识,当列的特定属性被改变时,触发表格刷新列
reColumnFlag: number
// 已标记的对象集
pendingRowMaps: Record<string, D | null>
// 已标记的行
pendingRowList: any[],
// 初始化标识
initStore: {
filter: boolean
@@ -2747,7 +2772,10 @@ export type VxeTableEmits = [
'toggle-tree-expand',
'menu-click',
'edit-closed',
'edit-actived',
'edit-actived', // 已废弃
'edit-activated',
'edit-disabled',
'valid-error',
'scroll',