feat: table grid supports setting title and helpMessage (#4732)

This commit is contained in:
Vben 2024-10-24 22:51:04 +08:00 committed by GitHub
parent 39e41d05be
commit 6688a6b3c2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 611 additions and 439 deletions

View File

@ -11,7 +11,10 @@ setupVbenVxeTable({
vxeUI.setConfig({ vxeUI.setConfig({
grid: { grid: {
align: 'center', align: 'center',
border: true, border: false,
columnConfig: {
resizable: true,
},
minHeight: 180, minHeight: 180,
proxyConfig: { proxyConfig: {
autoLoad: true, autoLoad: true,
@ -24,6 +27,7 @@ setupVbenVxeTable({
showResponseMsg: false, showResponseMsg: false,
}, },
round: true, round: true,
showOverflow: true,
size: 'small', size: 'small',
}, },
}); });

View File

@ -11,7 +11,10 @@ setupVbenVxeTable({
vxeUI.setConfig({ vxeUI.setConfig({
grid: { grid: {
align: 'center', align: 'center',
border: true, border: false,
columnConfig: {
resizable: true,
},
minHeight: 180, minHeight: 180,
proxyConfig: { proxyConfig: {
autoLoad: true, autoLoad: true,
@ -24,6 +27,7 @@ setupVbenVxeTable({
showResponseMsg: false, showResponseMsg: false,
}, },
round: true, round: true,
showOverflow: true,
size: 'small', size: 'small',
}, },
}); });

View File

@ -11,7 +11,10 @@ setupVbenVxeTable({
vxeUI.setConfig({ vxeUI.setConfig({
grid: { grid: {
align: 'center', align: 'center',
border: true, border: false,
columnConfig: {
resizable: true,
},
minHeight: 180, minHeight: 180,
proxyConfig: { proxyConfig: {
autoLoad: true, autoLoad: true,
@ -24,6 +27,7 @@ setupVbenVxeTable({
showResponseMsg: false, showResponseMsg: false,
}, },
round: true, round: true,
showOverflow: true,
size: 'small', size: 'small',
}, },
}); });

View File

@ -40,8 +40,5 @@
"pkg-types": "catalog:", "pkg-types": "catalog:",
"prettier": "catalog:", "prettier": "catalog:",
"rimraf": "catalog:" "rimraf": "catalog:"
},
"devDependencies": {
"@types/chalk": "catalog:"
} }
} }

View File

@ -29,7 +29,7 @@ export class ModalApi {
} = options; } = options;
const defaultState: ModalState = { const defaultState: ModalState = {
bordered: false, bordered: true,
centered: false, centered: false,
class: '', class: '',
closeOnClickModal: true, closeOnClickModal: true,

View File

@ -258,7 +258,13 @@ function handleFocusOutside(e: Event) {
v-if="showFooter" v-if="showFooter"
ref="footerRef" ref="footerRef"
:class=" :class="
cn('flex-row items-center justify-end border-t p-2', footerClass) cn(
'flex-row items-center justify-end p-2',
{
'border-t': bordered,
},
footerClass,
)
" "
> >
<slot name="prepend-footer"></slot> <slot name="prepend-footer"></slot>

View File

@ -8,6 +8,7 @@
/* base */ /* base */
--vxe-ui-base-popup-border-color: hsl(var(--border)); --vxe-ui-base-popup-border-color: hsl(var(--border));
--vxe-ui-input-disabled-color: hsl(var(--border) / 60%);
/* --vxe-ui-base-popup-box-shadow: 0px 12px 30px 8px rgb(0 0 0 / 50%); */ /* --vxe-ui-base-popup-box-shadow: 0px 12px 30px 8px rgb(0 0 0 / 50%); */

View File

@ -19,6 +19,14 @@ export interface VxePaginationInfo {
} }
export interface VxeGridProps { export interface VxeGridProps {
/**
*
*/
tableTitle?: string;
/**
*
*/
tableTitleHelp?: string;
/** /**
* class * class
*/ */

View File

@ -22,7 +22,7 @@ import { EmptyIcon } from '@vben/icons';
import { $t } from '@vben/locales'; import { $t } from '@vben/locales';
import { usePreferences } from '@vben/preferences'; import { usePreferences } from '@vben/preferences';
import { cloneDeep, cn, mergeWithArrayOverride } from '@vben/utils'; import { cloneDeep, cn, mergeWithArrayOverride } from '@vben/utils';
import { VbenLoading } from '@vben-core/shadcn-ui'; import { VbenHelpTooltip, VbenLoading } from '@vben-core/shadcn-ui';
import { VxeGrid, VxeUI } from 'vxe-table'; import { VxeGrid, VxeUI } from 'vxe-table';
@ -51,6 +51,8 @@ const {
gridClass, gridClass,
gridEvents, gridEvents,
formOptions, formOptions,
tableTitle,
tableTitleHelp,
} = usePriorityValues(props, state); } = usePriorityValues(props, state);
const { isMobile } = usePreferences(); const { isMobile } = usePreferences();
@ -79,31 +81,45 @@ const [Form, formApi] = useTableForm({
wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3', wrapperClass: 'grid-cols-1 md:grid-cols-2 lg:grid-cols-3',
}); });
const showTableTitle = computed(() => {
return !!slots.tableTitle?.() || tableTitle.value;
});
const showToolbar = computed(() => { const showToolbar = computed(() => {
return !!slots['toolbar-actions']?.() || !!slots['toolbar-tools']?.(); return (
!!slots['toolbar-actions']?.() ||
!!slots['toolbar-tools']?.() ||
showTableTitle.value
);
});
const toolbarOptions = computed(() => {
const slotActions = slots['toolbar-actions']?.();
const slotTools = slots['toolbar-tools']?.();
if (!showToolbar.value) {
return {};
}
// 使toolbar
//
return {
toolbarConfig: {
slots: {
...(slotActions || showTableTitle.value
? { buttons: 'toolbar-actions' }
: {}),
...(slotTools ? { tools: 'toolbar-tools' } : {}),
},
},
};
}); });
const options = computed(() => { const options = computed(() => {
const slotActions = slots['toolbar-actions']?.();
const slotTools = slots['toolbar-tools']?.();
const globalGridConfig = VxeUI?.getConfig()?.grid ?? {}; const globalGridConfig = VxeUI?.getConfig()?.grid ?? {};
const forceUseToolbarOptions = showToolbar.value
? {
toolbarConfig: {
slots: {
...(slotActions ? { buttons: 'toolbar-actions' } : {}),
...(slotTools ? { tools: 'toolbar-tools' } : {}),
},
},
}
: {};
const mergedOptions: VxeTableGridProps = cloneDeep( const mergedOptions: VxeTableGridProps = cloneDeep(
mergeWithArrayOverride( mergeWithArrayOverride(
{}, {},
forceUseToolbarOptions, toolbarOptions.value,
toRaw(gridOptions.value), toRaw(gridOptions.value),
globalGridConfig, globalGridConfig,
), ),
@ -164,7 +180,7 @@ const delegatedSlots = computed(() => {
const resultSlots: string[] = []; const resultSlots: string[] = [];
for (const key of Object.keys(slots)) { for (const key of Object.keys(slots)) {
if (!['empty', 'form', 'loading'].includes(key)) { if (!['empty', 'form', 'loading', 'toolbar-actions'].includes(key)) {
resultSlots.push(key); resultSlots.push(key);
} }
} }
@ -209,6 +225,7 @@ async function init() {
extendProxyOptions(props.api, defaultGridOptions, () => formApi.form.values); extendProxyOptions(props.api, defaultGridOptions, () => formApi.form.values);
} }
// formOptions
watch( watch(
formOptions, formOptions,
() => { () => {
@ -251,6 +268,20 @@ onMounted(() => {
v-bind="options" v-bind="options"
v-on="events" v-on="events"
> >
<!-- 左侧操作区域或者title -->
<template v-if="showToolbar" #toolbar-actions="slotProps">
<slot v-if="showTableTitle" name="table-title">
<div class="mr-1 pl-1 text-[1rem]">
{{ tableTitle }}
<VbenHelpTooltip v-if="tableTitleHelp" trigger-class="pb-1">
{{ tableTitleHelp }}
</VbenHelpTooltip>
</div>
</slot>
<slot name="toolbar-actions" v-bind="slotProps"> </slot>
</template>
<!-- 继承默认的slot -->
<template <template
v-for="slotName in delegatedSlots" v-for="slotName in delegatedSlots"
:key="slotName" :key="slotName"
@ -258,6 +289,8 @@ onMounted(() => {
> >
<slot :name="slotName" v-bind="slotProps"></slot> <slot :name="slotName" v-bind="slotProps"></slot>
</template> </template>
<!-- form表单 -->
<template #form> <template #form>
<div v-if="formOptions" class="relative rounded py-3 pb-4"> <div v-if="formOptions" class="relative rounded py-3 pb-4">
<slot name="form"> <slot name="form">
@ -291,11 +324,13 @@ onMounted(() => {
></div> ></div>
</div> </div>
</template> </template>
<!-- loading -->
<template #loading> <template #loading>
<slot name="loading"> <slot name="loading">
<VbenLoading :spinning="true" /> <VbenLoading :spinning="true" />
</slot> </slot>
</template> </template>
<!-- 统一控状态 -->
<template #empty> <template #empty>
<slot name="empty"> <slot name="empty">
<EmptyIcon class="mx-auto" /> <EmptyIcon class="mx-auto" />

View File

@ -11,7 +11,10 @@ setupVbenVxeTable({
vxeUI.setConfig({ vxeUI.setConfig({
grid: { grid: {
align: 'center', align: 'center',
border: true, border: false,
columnConfig: {
resizable: true,
},
minHeight: 180, minHeight: 180,
proxyConfig: { proxyConfig: {
autoLoad: true, autoLoad: true,
@ -24,6 +27,7 @@ setupVbenVxeTable({
showResponseMsg: false, showResponseMsg: false,
}, },
round: true, round: true,
showOverflow: true,
size: 'small', size: 'small',
}, },
}); });

View File

@ -76,10 +76,10 @@ function changeLoading() {
<template #extra> <template #extra>
<DocButton path="/components/common-ui/vben-vxe-table" /> <DocButton path="/components/common-ui/vben-vxe-table" />
</template> </template>
<Grid> <Grid table-title="基础列表" table-title-help="提示">
<template #toolbar-actions> <!-- <template #toolbar-actions>
<Button class="mr-2" type="primary">左侧插槽</Button> <Button class="mr-2" type="primary">左侧插槽</Button>
</template> </template> -->
<template #toolbar-tools> <template #toolbar-tools>
<Button class="mr-2" type="primary" @click="changeBorder"> <Button class="mr-2" type="primary" @click="changeBorder">
{{ showBorder ? '隐藏' : '显示' }}边框 {{ showBorder ? '隐藏' : '显示' }}边框

View File

@ -51,7 +51,7 @@ const [Grid, gridApi] = useVbenVxeGrid({ gridOptions });
<template> <template>
<Page auto-content-height> <Page auto-content-height>
<Grid> <Grid table-title="数据列表" table-title-help="提示">
<template #toolbar-tools> <template #toolbar-tools>
<Button class="mr-2" type="primary" @click="() => gridApi.query()"> <Button class="mr-2" type="primary" @click="() => gridApi.query()">
刷新当前页面 刷新当前页面

View File

@ -50,7 +50,7 @@ const collapseAll = () => {
<template> <template>
<Page> <Page>
<Grid> <Grid table-title="数据列表" table-title-help="提示">
<template #toolbar-tools> <template #toolbar-tools>
<Button class="mr-2" type="primary" @click="expandAll"> <Button class="mr-2" type="primary" @click="expandAll">
展开全部 展开全部

898
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -22,7 +22,7 @@ catalog:
'@ctrl/tinycolor': ^4.1.0 '@ctrl/tinycolor': ^4.1.0
'@eslint/js': ^9.13.0 '@eslint/js': ^9.13.0
'@faker-js/faker': ^9.0.3 '@faker-js/faker': ^9.0.3
'@iconify/json': ^2.2.262 '@iconify/json': ^2.2.263
'@iconify/tailwind': ^1.1.3 '@iconify/tailwind': ^1.1.3
'@iconify/vue': ^4.1.2 '@iconify/vue': ^4.1.2
'@intlify/core-base': ^10.0.4 '@intlify/core-base': ^10.0.4
@ -35,22 +35,21 @@ catalog:
'@stylistic/stylelint-plugin': ^3.1.1 '@stylistic/stylelint-plugin': ^3.1.1
'@tailwindcss/nesting': 0.0.0-insiders.565cd3e '@tailwindcss/nesting': 0.0.0-insiders.565cd3e
'@tailwindcss/typography': ^0.5.15 '@tailwindcss/typography': ^0.5.15
'@tanstack/vue-query': ^5.59.13 '@tanstack/vue-query': ^5.59.16
'@tanstack/vue-store': ^0.5.6 '@tanstack/vue-store': ^0.5.6
'@types/archiver': ^6.0.2 '@types/archiver': ^6.0.3
'@types/chalk': ^2.2.0
'@types/eslint': ^9.6.1 '@types/eslint': ^9.6.1
'@types/html-minifier-terser': ^7.0.2 '@types/html-minifier-terser': ^7.0.2
'@types/jsonwebtoken': ^9.0.7 '@types/jsonwebtoken': ^9.0.7
'@types/lodash.clonedeep': ^4.5.9 '@types/lodash.clonedeep': ^4.5.9
'@types/node': ^22.7.8 '@types/node': ^22.7.9
'@types/nprogress': ^0.2.3 '@types/nprogress': ^0.2.3
'@types/postcss-import': ^14.0.3 '@types/postcss-import': ^14.0.3
'@types/qrcode': ^1.5.5 '@types/qrcode': ^1.5.5
'@types/sortablejs': ^1.15.8 '@types/sortablejs': ^1.15.8
'@typescript-eslint/eslint-plugin': ^8.11.0 '@typescript-eslint/eslint-plugin': ^8.11.0
'@typescript-eslint/parser': ^8.11.0 '@typescript-eslint/parser': ^8.11.0
'@vee-validate/zod': ^4.14.3 '@vee-validate/zod': ^4.14.4
'@vite-pwa/vitepress': ^0.5.3 '@vite-pwa/vitepress': ^0.5.3
'@vitejs/plugin-vue': ^5.1.4 '@vitejs/plugin-vue': ^5.1.4
'@vitejs/plugin-vue-jsx': ^4.0.1 '@vitejs/plugin-vue-jsx': ^4.0.1
@ -127,11 +126,11 @@ catalog:
postcss-antd-fixes: ^0.2.0 postcss-antd-fixes: ^0.2.0
postcss-html: ^1.7.0 postcss-html: ^1.7.0
postcss-import: ^16.1.0 postcss-import: ^16.1.0
postcss-preset-env: ^10.0.7 postcss-preset-env: ^10.0.8
postcss-scss: ^4.0.9 postcss-scss: ^4.0.9
prettier: ^3.3.3 prettier: ^3.3.3
prettier-plugin-tailwindcss: ^0.6.8 prettier-plugin-tailwindcss: ^0.6.8
publint: ^0.2.11 publint: ^0.2.12
qrcode: ^1.5.4 qrcode: ^1.5.4
radix-vue: ^1.9.7 radix-vue: ^1.9.7
resolve.exports: ^2.0.2 resolve.exports: ^2.0.2
@ -157,15 +156,15 @@ catalog:
typescript: ^5.6.3 typescript: ^5.6.3
unbuild: ^2.0.0 unbuild: ^2.0.0
unplugin-element-plus: ^0.8.0 unplugin-element-plus: ^0.8.0
vee-validate: ^4.14.3 vee-validate: ^4.14.4
vite: ^5.4.9 vite: ^5.4.10
vite-plugin-compression: ^0.5.1 vite-plugin-compression: ^0.5.1
vite-plugin-dts: 4.2.1 vite-plugin-dts: 4.2.1
vite-plugin-html: ^3.2.2 vite-plugin-html: ^3.2.2
vite-plugin-lazy-import: ^1.0.7 vite-plugin-lazy-import: ^1.0.7
vite-plugin-lib-inject-css: ^2.1.1 vite-plugin-lib-inject-css: ^2.1.1
vite-plugin-pwa: ^0.20.5 vite-plugin-pwa: ^0.20.5
vite-plugin-vue-devtools: ^7.5.2 vite-plugin-vue-devtools: ^7.5.3
vitepress: ^1.4.1 vitepress: ^1.4.1
vitepress-plugin-group-icons: ^1.3.0 vitepress-plugin-group-icons: ^1.3.0
vitest: ^2.1.3 vitest: ^2.1.3
@ -174,8 +173,8 @@ catalog:
vue-i18n: ^10.0.4 vue-i18n: ^10.0.4
vue-router: ^4.4.5 vue-router: ^4.4.5
vue-tsc: ^2.1.6 vue-tsc: ^2.1.6
vxe-pc-ui: ^4.2.26 vxe-pc-ui: ^4.2.28
vxe-table: ^4.7.93 vxe-table: ^4.7.94
watermark-js-plus: ^1.5.7 watermark-js-plus: ^1.5.7
zod: ^3.23.8 zod: ^3.23.8
zod-defaults: ^0.1.3 zod-defaults: ^0.1.3