From 316fc05c52f11acc50e0431d8615e317e5917ba0 Mon Sep 17 00:00:00 2001 From: puhui999 Date: Sat, 7 Jun 2025 14:16:05 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=80=90ele=E3=80=91=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=20general=20=E5=8D=95=E8=A1=A8=E4=BB=A3=E7=A0=81=E7=94=9F?= =?UTF-8?q?=E6=88=90=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/web-ele/src/adapter/style.css | 79 +++++ apps/web-ele/src/adapter/vxe-table.ts | 2 + .../components/content-wrap/content-wrap.vue | 53 +++ .../src/components/content-wrap/index.ts | 1 + .../src/components/table-toolbar/index.ts | 1 + .../table-toolbar/table-toolbar.vue | 79 +++++ apps/web-ele/src/hooks/index.ts | 1 + apps/web-ele/src/hooks/use-table-toolbar.ts | 47 +++ .../views/infra/demo/general/demo01/index.vue | 316 ++++++++++++++++++ .../demo/general/demo01/modules/form.vue | 145 ++++++++ 10 files changed, 724 insertions(+) create mode 100644 apps/web-ele/src/adapter/style.css create mode 100644 apps/web-ele/src/components/content-wrap/content-wrap.vue create mode 100644 apps/web-ele/src/components/content-wrap/index.ts create mode 100644 apps/web-ele/src/components/table-toolbar/index.ts create mode 100644 apps/web-ele/src/components/table-toolbar/table-toolbar.vue create mode 100644 apps/web-ele/src/hooks/index.ts create mode 100644 apps/web-ele/src/hooks/use-table-toolbar.ts create mode 100644 apps/web-ele/src/views/infra/demo/general/demo01/index.vue create mode 100644 apps/web-ele/src/views/infra/demo/general/demo01/modules/form.vue diff --git a/apps/web-ele/src/adapter/style.css b/apps/web-ele/src/adapter/style.css new file mode 100644 index 000000000..01368a928 --- /dev/null +++ b/apps/web-ele/src/adapter/style.css @@ -0,0 +1,79 @@ +/* 来自 @vben/plugins/vxe-table style.css,覆盖 vxe-table 原有的样式定义,使用 vben 的样式主题 */ +:root { + --vxe-ui-font-color: hsl(var(--foreground)); + --vxe-ui-font-primary-color: hsl(var(--primary)); + + /* --vxe-ui-font-lighten-color: #babdc0; + --vxe-ui-font-darken-color: #86898e; */ + --vxe-ui-font-disabled-color: hsl(var(--foreground) / 50%); + + /* base */ + --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%); */ + + /* layout */ + --vxe-ui-layout-background-color: hsl(var(--background)); + --vxe-ui-table-resizable-line-color: hsl(var(--heavy)); + + /* --vxe-ui-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px hsl(var(--accent)); + --vxe-ui-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px hsl(var(--accent)); */ + + /* input */ + --vxe-ui-input-border-color: hsl(var(--border)); + + /* --vxe-ui-input-placeholder-color: #8d9095; */ + + /* --vxe-ui-input-disabled-background-color: #262727; */ + + /* loading */ + --vxe-ui-loading-background-color: hsl(var(--overlay-content)); + + /* table */ + --vxe-ui-table-header-background-color: hsl(var(--accent)); + --vxe-ui-table-border-color: hsl(var(--border)); + --vxe-ui-table-row-hover-background-color: hsl(var(--accent-hover)); + --vxe-ui-table-row-striped-background-color: hsl(var(--accent) / 60%); + --vxe-ui-table-row-hover-striped-background-color: hsl(var(--accent)); + --vxe-ui-table-row-radio-checked-background-color: hsl(var(--accent)); + --vxe-ui-table-row-hover-radio-checked-background-color: hsl( + var(--accent-hover) + ); + --vxe-ui-table-row-checkbox-checked-background-color: hsl(var(--accent)); + --vxe-ui-table-row-hover-checkbox-checked-background-color: hsl( + var(--accent-hover) + ); + --vxe-ui-table-row-current-background-color: hsl(var(--accent)); + --vxe-ui-table-row-hover-current-background-color: hsl(var(--accent-hover)); + --vxe-ui-font-primary-tinge-color: hsl(var(--primary)); + --vxe-ui-font-primary-lighten-color: hsl(var(--primary) / 60%); + --vxe-ui-font-primary-darken-color: hsl(var(--primary)); + + /* height: auto !important; */ + + /* --vxe-ui-table-fixed-scrolling-box-shadow-color: rgb(0 0 0 / 80%); */ +} + +.vxe-tools--operate { + margin-right: 0.25rem; + margin-left: 0.75rem; +} + +.vxe-table-custom--checkbox-option:hover { + background: none !important; +} + +.vxe-toolbar { + padding: 0; +} + +.vxe-buttons--wrapper:not(:empty), +.vxe-tools--operate:not(:empty), +.vxe-tools--wrapper:not(:empty) { + padding: 0.6em 0; +} + +.vxe-tools--operate:not(:has(button)) { + margin-left: 0; +} diff --git a/apps/web-ele/src/adapter/vxe-table.ts b/apps/web-ele/src/adapter/vxe-table.ts index cba828957..c583d97d6 100644 --- a/apps/web-ele/src/adapter/vxe-table.ts +++ b/apps/web-ele/src/adapter/vxe-table.ts @@ -18,6 +18,8 @@ import { $t } from '#/locales'; import { useVbenForm } from './form'; +import '#/adapter/style.css'; + setupVbenVxeTable({ configVxeTable: (vxeUI) => { vxeUI.setConfig({ diff --git a/apps/web-ele/src/components/content-wrap/content-wrap.vue b/apps/web-ele/src/components/content-wrap/content-wrap.vue new file mode 100644 index 000000000..c02ec6e00 --- /dev/null +++ b/apps/web-ele/src/components/content-wrap/content-wrap.vue @@ -0,0 +1,53 @@ + + + + diff --git a/apps/web-ele/src/components/content-wrap/index.ts b/apps/web-ele/src/components/content-wrap/index.ts new file mode 100644 index 000000000..d4f95fddb --- /dev/null +++ b/apps/web-ele/src/components/content-wrap/index.ts @@ -0,0 +1 @@ +export { default as ContentWrap } from './content-wrap.vue'; diff --git a/apps/web-ele/src/components/table-toolbar/index.ts b/apps/web-ele/src/components/table-toolbar/index.ts new file mode 100644 index 000000000..720e3224b --- /dev/null +++ b/apps/web-ele/src/components/table-toolbar/index.ts @@ -0,0 +1 @@ +export { default as TableToolbar } from './table-toolbar.vue'; diff --git a/apps/web-ele/src/components/table-toolbar/table-toolbar.vue b/apps/web-ele/src/components/table-toolbar/table-toolbar.vue new file mode 100644 index 000000000..e9f64778b --- /dev/null +++ b/apps/web-ele/src/components/table-toolbar/table-toolbar.vue @@ -0,0 +1,79 @@ + + + + diff --git a/apps/web-ele/src/hooks/index.ts b/apps/web-ele/src/hooks/index.ts new file mode 100644 index 000000000..75f01b531 --- /dev/null +++ b/apps/web-ele/src/hooks/index.ts @@ -0,0 +1 @@ +export * from './use-table-toolbar'; diff --git a/apps/web-ele/src/hooks/use-table-toolbar.ts b/apps/web-ele/src/hooks/use-table-toolbar.ts new file mode 100644 index 000000000..c35b3a774 --- /dev/null +++ b/apps/web-ele/src/hooks/use-table-toolbar.ts @@ -0,0 +1,47 @@ +import type { VxeTableInstance, VxeToolbarInstance } from '#/adapter/vxe-table'; +import type { TableToolbar } from '#/components/table-toolbar'; + +import { ref, watch } from 'vue'; + +/** + * vxe 原生工具栏挂载封装 + * 解决每个组件使用 vxe-table 组件时都需要写一遍的问题 + */ +export function useTableToolbar() { + const hiddenSearchBar = ref(false); // 隐藏搜索栏 + const tableToolbarRef = ref>(); + const tableRef = ref(); + const isBound = ref(false); + + /** 挂载 toolbar 工具栏 */ + async function bindTableToolbar() { + const table = tableRef.value; + const tableToolbar = tableToolbarRef.value; + if (table && tableToolbar) { + // 延迟 1 秒,确保 toolbar 组件已经挂载 + setTimeout(async () => { + const toolbar = tableToolbar.getToolbarRef(); + if (!toolbar) { + console.error('[toolbar 挂载失败] Table toolbar not found'); + } + await table.connect(toolbar as VxeToolbarInstance); + isBound.value = true; + }, 1000); // 延迟挂载确保 toolbar 正确挂载 + } + } + + watch( + () => tableRef.value, + async (val) => { + if (!val || isBound.value) return; + await bindTableToolbar(); + }, + { immediate: true }, + ); + + return { + hiddenSearchBar, + tableToolbarRef, + tableRef, + }; +} diff --git a/apps/web-ele/src/views/infra/demo/general/demo01/index.vue b/apps/web-ele/src/views/infra/demo/general/demo01/index.vue new file mode 100644 index 000000000..4e16a6292 --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/general/demo01/index.vue @@ -0,0 +1,316 @@ + + + diff --git a/apps/web-ele/src/views/infra/demo/general/demo01/modules/form.vue b/apps/web-ele/src/views/infra/demo/general/demo01/modules/form.vue new file mode 100644 index 000000000..1f6aa6fc3 --- /dev/null +++ b/apps/web-ele/src/views/infra/demo/general/demo01/modules/form.vue @@ -0,0 +1,145 @@ + + +