mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-01-23 09:40:25 +08:00
feat: table grid supports setting title and helpMessage (#4732)
This commit is contained in:
parent
39e41d05be
commit
6688a6b3c2
@ -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',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -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',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -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',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -40,8 +40,5 @@
|
|||||||
"pkg-types": "catalog:",
|
"pkg-types": "catalog:",
|
||||||
"prettier": "catalog:",
|
"prettier": "catalog:",
|
||||||
"rimraf": "catalog:"
|
"rimraf": "catalog:"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/chalk": "catalog:"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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>
|
||||||
|
@ -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%); */
|
||||||
|
|
||||||
|
@ -19,6 +19,14 @@ export interface VxePaginationInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface VxeGridProps {
|
export interface VxeGridProps {
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
tableTitle?: string;
|
||||||
|
/**
|
||||||
|
* 标题帮助
|
||||||
|
*/
|
||||||
|
tableTitleHelp?: string;
|
||||||
/**
|
/**
|
||||||
* 组件class
|
* 组件class
|
||||||
*/
|
*/
|
||||||
|
@ -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" />
|
||||||
|
@ -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',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -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 ? '隐藏' : '显示' }}边框
|
||||||
|
@ -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()">
|
||||||
刷新当前页面
|
刷新当前页面
|
||||||
|
@ -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
898
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user