feat(@vben/web-antd): 验证样式

- 添加 isValidating 状态管理,用于控制验证过程
- 在表格列定义中增加验证错误样式
- 实现必填字段错误提示功能
- 优化表格渲染逻辑,确保验证错误及时显示
- 新增相关 CSS 样式,定义验证错误的视觉效果
pull/188/head
nehc 2025-08-02 21:21:51 +08:00
parent 9d80b9fc71
commit 5f56b14733
3 changed files with 67 additions and 2 deletions

View File

@ -98,7 +98,9 @@ export function useFormSchema(): VbenFormSchema[] {
}
/** 入库产品清单表格列定义 */
export function useStockInItemTableColumns(): VxeTableGridOptions['columns'] {
export function useStockInItemTableColumns(
isValidating?: any,
): VxeTableGridOptions['columns'] {
return [
{ type: 'seq', title: '序号', minWidth: 50, fixed: 'left' },
{
@ -106,12 +108,22 @@ export function useStockInItemTableColumns(): VxeTableGridOptions['columns'] {
title: '仓库名称',
minWidth: 150,
slots: { default: 'warehouseId' },
className: ({ row }: { row: any }) => {
return isValidating?.value && !row.warehouseId
? 'required-field-error'
: '';
},
},
{
field: 'productId',
title: '产品名称',
minWidth: 200,
slots: { default: 'productId' },
className: ({ row }: { row: any }) => {
return isValidating?.value && !row.productId
? 'required-field-error'
: '';
},
},
{
field: 'stockCount',
@ -133,6 +145,11 @@ export function useStockInItemTableColumns(): VxeTableGridOptions['columns'] {
title: '数量',
minWidth: 120,
slots: { default: 'count' },
className: ({ row }: { row: any }) => {
return isValidating?.value && (!row.count || row.count <= 0)
? 'required-field-error'
: '';
},
},
{
field: 'productPrice',

View File

@ -29,6 +29,7 @@ interface Props {
const tableData = ref<ErpStockInApi.StockInItem[]>([]);
const productOptions = ref<any[]>([]);
const warehouseOptions = ref<any[]>([]);
const isValidating = ref(false);
/** 表格配置 */
const [Grid, gridApi] = useVbenVxeGrid({
@ -37,7 +38,7 @@ const [Grid, gridApi] = useVbenVxeGrid({
trigger: 'click',
mode: 'cell',
},
columns: useStockInItemTableColumns(),
columns: useStockInItemTableColumns(isValidating),
data: tableData.value,
border: true,
showOverflow: true,
@ -116,6 +117,10 @@ function handleAdd() {
tableData.value.push(newRow);
gridApi.grid.insertAt(newRow, -1);
emit('update:items', [...tableData.value]);
// cellClassName
nextTick(() => {
gridApi.grid.refreshColumn();
});
}
function handleDelete(row: ErpStockInApi.StockInItem) {
@ -182,6 +187,10 @@ function handleUpdateValue(row: any) {
tableData.value[index] = row;
}
emit('update:items', [...tableData.value]);
// cellClassName
nextTick(() => {
gridApi.grid.refreshColumn();
});
}
const getSummaries = (): {
@ -200,6 +209,13 @@ const getSummaries = (): {
/** 验证表单 */
function validate(): Promise<boolean> {
return new Promise((resolve) => {
isValidating.value = true;
//
nextTick(() => {
gridApi.grid.refreshColumn();
});
//
if (!tableData.value || tableData.value.length === 0) {
resolve(false);
@ -219,6 +235,12 @@ function validate(): Promise<boolean> {
}
}
//
isValidating.value = false;
nextTick(() => {
gridApi.grid.refreshColumn();
});
resolve(true);
});
}

View File

@ -115,3 +115,29 @@
.vxe-grid--layout-body-content-wrapper {
overflow: hidden;
}
/* 必填字段错误样式 */
.vxe-table .required-field-error::after {
position: absolute;
top: -1px;
right: -1px;
z-index: 10;
padding: 1px 4px;
font-size: 10px;
line-height: 1;
color: white;
content: '必填';
background-color: #ff4d4f;
border-radius: 0 0 0 4px;
}
/* 必填字段内的输入框样式 */
.vxe-table .required-field-error .ant-select,
.vxe-table .required-field-error .ant-input-number,
.vxe-table .required-field-error .ant-input {
border-color: #ff4d4f !important;
}
.vxe-table .required-field-error .ant-select .ant-select-selector {
border-color: #ff4d4f !important;
}