!63 feat(vxetable): ✨ 适配 vxetable 4.7+
Merge pull request !63 from cshaptx4869/gitee-patch-1
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
"@form-create/designer": "3.5.0",
|
||||
"@form-create/element-ui": "3.3.3",
|
||||
"@vueuse/core": "^14.4.0",
|
||||
"@vxe-ui/plugin-export-xlsx": "^4.5.4",
|
||||
"@wangeditor-next/editor": "^5.7.16",
|
||||
"@wangeditor-next/editor-for-vue": "^5.1.14",
|
||||
"animate.css": "^4.1.1",
|
||||
@@ -73,7 +74,9 @@
|
||||
"vue-draggable-plus": "^0.6.1",
|
||||
"vue-i18n": "^11.4.8",
|
||||
"vue-router": "^5.2.0",
|
||||
"vxe-table": "~4.6.25"
|
||||
"vxe-pc-ui": "^4.18.9",
|
||||
"vxe-table": "^4.21.10",
|
||||
"xe-utils": "^4.0.13"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@commitlint/cli": "^21.2.1",
|
||||
|
||||
82
pnpm-lock.yaml
generated
82
pnpm-lock.yaml
generated
@@ -20,6 +20,9 @@ importers:
|
||||
'@vueuse/core':
|
||||
specifier: ^14.4.0
|
||||
version: 14.4.0(vue@3.5.42(typescript@6.0.3))
|
||||
'@vxe-ui/plugin-export-xlsx':
|
||||
specifier: ^4.5.4
|
||||
version: 4.5.4(vxe-table@4.21.10)
|
||||
'@wangeditor-next/editor':
|
||||
specifier: ^5.7.16
|
||||
version: 5.7.16
|
||||
@@ -86,9 +89,15 @@ importers:
|
||||
vue-router:
|
||||
specifier: ^5.2.0
|
||||
version: 5.3.1(@vue/compiler-sfc@3.5.42)(pinia@4.0.3(@vue/devtools-api@8.2.1)(typescript@6.0.3)(vue@3.5.42(typescript@6.0.3)))(rolldown@1.2.7)(vite@8.2.2(@types/node@26.4.1)(jiti@2.7.0)(sass@1.104.0)(terser@5.51.2)(yaml@2.9.0))(vue@3.5.42(typescript@6.0.3))
|
||||
vxe-pc-ui:
|
||||
specifier: ^4.18.9
|
||||
version: 4.18.9(vue@3.5.42(typescript@6.0.3))
|
||||
vxe-table:
|
||||
specifier: ~4.6.25
|
||||
version: 4.6.25(vue@3.5.42(typescript@6.0.3))
|
||||
specifier: ^4.21.10
|
||||
version: 4.21.10
|
||||
xe-utils:
|
||||
specifier: ^4.0.13
|
||||
version: 4.0.13
|
||||
devDependencies:
|
||||
'@commitlint/cli':
|
||||
specifier: ^21.2.1
|
||||
@@ -742,56 +751,48 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-arm64-musl@0.131.0':
|
||||
resolution: {integrity: sha512-vtPiwmfVTAXzaxDKsOXG+LwgRAA7WEnaeHzhS5z0GE89gAK18KSXnly7Z6saXXq6L3dVMyK44uoTI03zKxrpmw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-ppc64-gnu@0.131.0':
|
||||
resolution: {integrity: sha512-8AW8L7w5cGHSdZPcyZX2yR0+GUODsT15rbRjfdD54rv6DMbtuEB19ysLOpKJlRGfH6UNYNpCHaU1uJWgTWf1/w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-gnu@0.131.0':
|
||||
resolution: {integrity: sha512-vvpjkjEOUsPcsYf8evE4MO3aGx9+3wodXEBOicGNnOwTuAik8eBONNkgSdhkGsAblQmfVHJyanRnpxglddTXIA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-riscv64-musl@0.131.0':
|
||||
resolution: {integrity: sha512-AqmcNC3fClXX+fxQ6VGEN1667xVFiRBkY0CZmDMSiaeFUsv1+UkBPYYi48IUKcA9/ivvoKNRzQl2I4//kT9F/w==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-linux-s390x-gnu@0.131.0':
|
||||
resolution: {integrity: sha512-7d3jOMKy7RSQCcDLIci+ySll2FgsOMl/GiRux4q2JNv0zg4EdhFISa9idvrdN/HEUIQQJNg6dmveUeJl2YErGA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-gnu@0.131.0':
|
||||
resolution: {integrity: sha512-JHK/h95qVqVQ+ITER837kcTdwBDFpFaNnOTYGCP0zdUSX/mLKC7tXOoyrTb6vG7iRPwGlcgBil3v2IjYw1FqJA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@oxc-parser/binding-linux-x64-musl@0.131.0':
|
||||
resolution: {integrity: sha512-b2BO82O8azXAyf7EUgOPKu145nWypbNyk07HbU09fkzhm9lEA5oPvaN/M8Nlo7tOErVTa2WOgS4QbOnxAPXdDQ==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@oxc-parser/binding-openharmony-arm64@0.131.0':
|
||||
resolution: {integrity: sha512-GHO9glZaX7LkX/OGfluEPf1yjg+ehiFbUdowbX6uNWOQhmwKWU4m4+nZ9FJkrHNKuxyI1KKertMdGjVKCApKWA==}
|
||||
@@ -860,42 +861,36 @@ packages:
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm-musl@2.6.0':
|
||||
resolution: {integrity: sha512-9c6AUHgHoG+IY88MRIHupztQiQnrbqHYQjkM2btA+Bf/wQnQMuiD0Wfk1EVv3TlNT3x41uU71rn6E4xh/+zvkw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-arm64-glibc@2.6.0':
|
||||
resolution: {integrity: sha512-yHRqS2owEXe6Hic9z6Mh1ECsCd+ODVOGvZDyciqRd21+v+o+DnXMOrw50DSpIG2sb8GPEaPPmfeCAWKPJdq46g==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-arm64-musl@2.6.0':
|
||||
resolution: {integrity: sha512-WhB2e/V7rqdHHWZusBSPuy5Ei8S6lSz6FE5TKKQz5h3a0O+C+mhY7vxU9b/stqvMb8beLnPY82ZrFTLKs+SrKA==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-linux-x64-glibc@2.6.0':
|
||||
resolution: {integrity: sha512-ulGE6x6Oz6iAwg75T8YQSoguBWasniIbX+QWpaYPcCnDOpdWX3k+4xbEYPZVLxOuoJI+svJJPD3sEj8G7lrQ3A==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@parcel/watcher-linux-x64-musl@2.6.0':
|
||||
resolution: {integrity: sha512-tkBYKt7YQrjIJWYDnto2YgO8MRkjlMTSNoRHzsXinBqbLdeOM3L32wPZJvIZxqaLMfSlS/4sUjH/6STVP/XDLw==}
|
||||
engines: {node: '>= 10.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@parcel/watcher-win32-arm64@2.6.0':
|
||||
resolution: {integrity: sha512-gIZAP23jaHjGWasY/TY6yL7NHFClf0Ga7FN+iINvk+KN94rhm94lYZhFsbYFNcA04/onvGD9kKmiJLJB2HbNwQ==}
|
||||
@@ -968,42 +963,36 @@ packages:
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-arm64-musl@1.2.7':
|
||||
resolution: {integrity: sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-linux-ppc64-gnu@1.2.7':
|
||||
resolution: {integrity: sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-s390x-gnu@1.2.7':
|
||||
resolution: {integrity: sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-gnu@1.2.7':
|
||||
resolution: {integrity: sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
'@rolldown/binding-linux-x64-musl@1.2.7':
|
||||
resolution: {integrity: sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==}
|
||||
engines: {node: ^20.19.0 || >=22.12.0}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
'@rolldown/binding-openharmony-arm64@1.2.7':
|
||||
resolution: {integrity: sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==}
|
||||
@@ -1384,6 +1373,16 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.5.0
|
||||
|
||||
'@vxe-ui/core@4.4.21':
|
||||
resolution: {integrity: sha512-xaKGhQxrSU3G7+cQbxMBSzNXiWliRDgtR5GmD/FD9f5tl8e9SuZLe2SfODjItp6oBvBkKI2TXBZiCx502WftyA==}
|
||||
peerDependencies:
|
||||
vue: ^3.2.0
|
||||
|
||||
'@vxe-ui/plugin-export-xlsx@4.5.4':
|
||||
resolution: {integrity: sha512-aG1K17m5mG4Mbs1WwY5d0e3rIEWcB319c+1P0Ma1kcaLL26NvMMUAGg8ChpACIhmRDYEJWJ36cVSU3sZ9VMZ/w==}
|
||||
peerDependencies:
|
||||
vxe-table: ^4.12
|
||||
|
||||
'@wangeditor-next/basic-modules@3.0.3':
|
||||
resolution: {integrity: sha512-Z+nBFCsgToh4Mx1zPX6QpIx4VJenuNXFQnEIoPbNR/b29gXEfL1Lnvj/sYDdq8tiLDxhryq175gvRlZyuwEq7w==}
|
||||
peerDependencies:
|
||||
@@ -2783,28 +2782,24 @@ packages:
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-arm64-musl@1.33.0:
|
||||
resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-linux-x64-gnu@1.33.0:
|
||||
resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [glibc]
|
||||
|
||||
lightningcss-linux-x64-musl@1.33.0:
|
||||
resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==}
|
||||
engines: {node: '>= 12.0.0'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
libc: [musl]
|
||||
|
||||
lightningcss-win32-arm64-msvc@1.33.0:
|
||||
resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==}
|
||||
@@ -4126,10 +4121,11 @@ packages:
|
||||
peerDependencies:
|
||||
vue: ^3.0.1
|
||||
|
||||
vxe-table@4.6.25:
|
||||
resolution: {integrity: sha512-rFhGh8w+420cdnIasQKisiKagz9F/iNieB/z6v0j4GcsMfGHEmSJ72YrHcXogQh4wNlCzKVfb7rl7nREL5eIOg==}
|
||||
peerDependencies:
|
||||
vue: ^3.2.28
|
||||
vxe-pc-ui@4.18.9:
|
||||
resolution: {integrity: sha512-TJk788bY4Ok2LIBWB3JakNNuq3lirigVhyRgvNw9c8CdkWn98fSgqkncijMtx9qgDZssgsvPF61YMEq9jCJ+zQ==}
|
||||
|
||||
vxe-table@4.21.10:
|
||||
resolution: {integrity: sha512-9O4Yi/gbafmW/x8qrhG8ZTCUrgGYFK6w3draMH+nsxkKjQhlhYgFvFmcJKOfL6+7VuDvMdQp8JXPi38MxdSb5Q==}
|
||||
|
||||
wangeditor@4.7.15:
|
||||
resolution: {integrity: sha512-aPTdREd8BxXVyJ5MI+LU83FQ7u1EPd341iXIorRNYSOvoimNoZ4nPg+yn3FGbB93/owEa6buLw8wdhYnMCJQLg==}
|
||||
@@ -4194,8 +4190,8 @@ packages:
|
||||
utf-8-validate:
|
||||
optional: true
|
||||
|
||||
xe-utils@3.9.1:
|
||||
resolution: {integrity: sha512-Ujk5UmoH6Iaqhgz3oGwfCXVcMdUJKlXnfvLABdnMyseMG0eHsX2mcCvLd/8sGlIXtfwsprI9bW7vgcVognLmqQ==}
|
||||
xe-utils@4.0.13:
|
||||
resolution: {integrity: sha512-hIxQ3LQv/WF0DyeNsZ7VclX5+n5CKoUJ3DG76GFtuAnVQ/NaSv3MKmyZ6MD73wfSdzZBcziV8wcas8GRNSYMwg==}
|
||||
|
||||
xml-name-validator@5.0.0:
|
||||
resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==}
|
||||
@@ -5514,6 +5510,16 @@ snapshots:
|
||||
dependencies:
|
||||
vue: 3.5.42(typescript@6.0.3)
|
||||
|
||||
'@vxe-ui/core@4.4.21(vue@3.5.42(typescript@6.0.3))':
|
||||
dependencies:
|
||||
dom-zindex: 1.0.7
|
||||
vue: 3.5.42(typescript@6.0.3)
|
||||
xe-utils: 4.0.13
|
||||
|
||||
'@vxe-ui/plugin-export-xlsx@4.5.4(vxe-table@4.21.10)':
|
||||
dependencies:
|
||||
vxe-table: 4.21.10
|
||||
|
||||
'@wangeditor-next/basic-modules@3.0.3(@wangeditor-next/core@1.9.5(@uppy/core@5.2.0)(@uppy/xhr-upload@5.2.0(@uppy/core@5.2.0))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.16)(slate@0.124.1)(snabbdom@3.6.4))(dom7@4.0.6)(lodash.throttle@4.1.1)(nanoid@5.1.16)(slate@0.124.1)(snabbdom@3.6.4)':
|
||||
dependencies:
|
||||
'@wangeditor-next/core': 1.9.5(@uppy/core@5.2.0)(@uppy/xhr-upload@5.2.0(@uppy/core@5.2.0))(dom7@4.0.6)(is-hotkey@0.2.0)(lodash.camelcase@4.3.0)(lodash.clonedeep@4.5.0)(lodash.debounce@4.0.8)(lodash.foreach@4.5.0)(lodash.throttle@4.1.1)(lodash.toarray@4.4.0)(nanoid@5.1.16)(slate@0.124.1)(snabbdom@3.6.4)
|
||||
@@ -8342,11 +8348,13 @@ snapshots:
|
||||
sortablejs: 1.14.0
|
||||
vue: 3.5.42(typescript@6.0.3)
|
||||
|
||||
vxe-table@4.6.25(vue@3.5.42(typescript@6.0.3)):
|
||||
vxe-pc-ui@4.18.9(vue@3.5.42(typescript@6.0.3)):
|
||||
dependencies:
|
||||
dom-zindex: 1.0.7
|
||||
vue: 3.5.42(typescript@6.0.3)
|
||||
xe-utils: 3.9.1
|
||||
'@vxe-ui/core': 4.4.21(vue@3.5.42(typescript@6.0.3))
|
||||
transitivePeerDependencies:
|
||||
- vue
|
||||
|
||||
vxe-table@4.21.10: {}
|
||||
|
||||
wangeditor@4.7.15:
|
||||
dependencies:
|
||||
@@ -8406,7 +8414,7 @@ snapshots:
|
||||
|
||||
ws@8.21.3: {}
|
||||
|
||||
xe-utils@3.9.1: {}
|
||||
xe-utils@4.0.13: {}
|
||||
|
||||
xml-name-validator@5.0.0: {}
|
||||
|
||||
|
||||
@@ -1,34 +1,76 @@
|
||||
/**
|
||||
* VxeTable 全局配置
|
||||
* @see https://vxetable.cn/v4.6/#/table/start/install
|
||||
*/
|
||||
// 引入样式
|
||||
import "vxe-pc-ui/lib/style.css";
|
||||
import "vxe-table/lib/style.css";
|
||||
// 导入主题变量,也可以重写主题变量
|
||||
import "vxe-pc-ui/styles/cssvar.scss";
|
||||
import "vxe-table/styles/cssvar.scss";
|
||||
// 导入默认的语言
|
||||
import enUS from "vxe-pc-ui/lib/language/en-US";
|
||||
import zhCN from "vxe-pc-ui/lib/language/zh-CN";
|
||||
import VxeUIPluginExportXLSX from "@vxe-ui/plugin-export-xlsx";
|
||||
import ExcelJS from "exceljs";
|
||||
import { VxeUI } from "vxe-pc-ui";
|
||||
|
||||
import VXETable from "vxe-table";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { DeviceEnum } from "@/enums";
|
||||
|
||||
export function configureVxeTable() {
|
||||
VXETable.setConfig({
|
||||
export function configureVxeUI() {
|
||||
const appStore = useAppStore();
|
||||
const isMobile = appStore.device === DeviceEnum.MOBILE;
|
||||
|
||||
// 导入导出xlsx插件 https://vxetable.cn/other4/#/table/plugin/exportXLSX
|
||||
VxeUI.use(VxeUIPluginExportXLSX, {
|
||||
ExcelJS,
|
||||
});
|
||||
|
||||
// 注册语言
|
||||
VxeUI.setI18n("zh-CN", zhCN);
|
||||
VxeUI.setI18n("en-US", enUS);
|
||||
// 切换指定语言
|
||||
VxeUI.setLanguage("zh-CN");
|
||||
|
||||
// 全局默认参数
|
||||
VxeUI.setConfig({
|
||||
// 全局尺寸
|
||||
size: "medium",
|
||||
// 全局 zIndex 起始值,默认是 999,如果项目的的 z-index 样式值过大时就需要跟随设置更大,避免被遮挡
|
||||
zIndex: 9999,
|
||||
// 版本号,对于某些带数据缓存的功能有用到,上升版本号可以用于重置数据
|
||||
version: 0,
|
||||
// 全局 loading 提示内容,如果为 null 则不显示文本
|
||||
loading: {
|
||||
showText: false,
|
||||
text: "",
|
||||
},
|
||||
table: {
|
||||
minHeight: 46,
|
||||
showHeader: true,
|
||||
showOverflow: "tooltip",
|
||||
showHeaderOverflow: "tooltip",
|
||||
showHeaderOverflow: isMobile ? false : "tooltip",
|
||||
autoResize: true,
|
||||
// stripe: false,
|
||||
border: "inner",
|
||||
// round: false,
|
||||
emptyText: "暂无数据",
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
isCurrent: true,
|
||||
// 行数据的唯一主键字段名
|
||||
keyField: "_VXE_ID",
|
||||
},
|
||||
columnConfig: {
|
||||
resizable: false,
|
||||
minWidth: isMobile ? "auto" : undefined,
|
||||
},
|
||||
align: "center",
|
||||
headerAlign: "center",
|
||||
validConfig: {
|
||||
theme: "normal",
|
||||
},
|
||||
},
|
||||
pager: {
|
||||
// size: "medium",
|
||||
// 配套的样式
|
||||
perfect: false,
|
||||
pageSize: 10,
|
||||
pagerCount: 7,
|
||||
@@ -44,11 +86,22 @@ export function configureVxeTable() {
|
||||
"FullJump",
|
||||
],
|
||||
},
|
||||
form: {
|
||||
span: isMobile ? 24 : 6,
|
||||
validConfig: {
|
||||
theme: "normal",
|
||||
},
|
||||
},
|
||||
modal: {
|
||||
minWidth: 500,
|
||||
minHeight: 400,
|
||||
fullscreen: isMobile,
|
||||
remember: isMobile,
|
||||
width: isMobile ? "95%" : undefined,
|
||||
// minWidth: 500,
|
||||
// minHeight: 400,
|
||||
lockView: true,
|
||||
mask: true,
|
||||
// duration: 3000,
|
||||
// marginSize: 20,
|
||||
dblclickZoom: false,
|
||||
showTitleOverflow: true,
|
||||
transfer: true,
|
||||
|
||||
@@ -7,96 +7,6 @@
|
||||
background-color: var(--el-color-primary);
|
||||
}
|
||||
|
||||
// VxeTable 变量覆写
|
||||
:root {
|
||||
--vxe-font-color: var(--el-text-color-regular);
|
||||
--vxe-primary-color: var(--el-color-primary);
|
||||
--vxe-success-color: var(--el-color-success);
|
||||
--vxe-info-color: var(--el-color-info);
|
||||
--vxe-warning-color: var(--el-color-warning);
|
||||
--vxe-danger-color: var(--el-color-danger);
|
||||
--vxe-font-lighten-color: var(--el-text-color-primary);
|
||||
--vxe-primary-lighten-color: var(--el-color-primary-light-3);
|
||||
--vxe-success-lighten-color: var(--el-color-success-light-3);
|
||||
--vxe-info-lighten-color: var(--el-color-info-light-3);
|
||||
--vxe-warning-lighten-color: var(--el-color-warning-light-3);
|
||||
--vxe-danger-lighten-color: var(--el-color-danger-light-3);
|
||||
--vxe-font-darken-color: var(--el-text-color-secondary);
|
||||
--vxe-primary-darken-color: var(--el-color-primary-dark-2);
|
||||
--vxe-success-darken-color: var(--el-color-success-dark-2);
|
||||
--vxe-info-darken-color: var(--el-color-info-dark-2);
|
||||
--vxe-warning-darken-color: var(--el-color-warning-dark-2);
|
||||
--vxe-danger-darken-color: var(--el-color-danger-dark-2);
|
||||
--vxe-font-disabled-color: var(--el-text-color-disabled);
|
||||
--vxe-primary-disabled-color: var(--el-color-primary-light-5);
|
||||
--vxe-success-disabled-color: var(--el-color-success-light-5);
|
||||
--vxe-info-disabled-color: var(--el-color-info-light-5);
|
||||
--vxe-warning-disabled-color: var(--el-color-warning-light-5);
|
||||
--vxe-danger-disabled-color: var(--el-color-danger-light-5);
|
||||
--vxe-input-border-color: var(--el-border-color);
|
||||
--vxe-input-disabled-color: var(--el-text-color-disabled);
|
||||
--vxe-input-disabled-background-color: var(--el-fill-color-light);
|
||||
--vxe-input-placeholder-color: var(--el-text-color-placeholder);
|
||||
--vxe-table-popup-border-color: var(--el-border-color);
|
||||
--vxe-table-header-font-color: var(--el-text-color-regular);
|
||||
--vxe-table-footer-font-color: var(--el-text-color-regular);
|
||||
--vxe-table-border-color: var(--el-border-color-lighter);
|
||||
--vxe-table-header-background-color: var(--el-bg-color);
|
||||
--vxe-table-body-background-color: var(--el-bg-color);
|
||||
--vxe-table-footer-background-color: var(--el-bg-color);
|
||||
--vxe-table-row-hover-background-color: var(--el-fill-color-light);
|
||||
--vxe-table-row-current-background-color: var(--el-fill-color-light);
|
||||
--vxe-table-row-hover-current-background-color: var(--el-fill-color-light);
|
||||
--vxe-table-checkbox-range-background-color: var(--el-fill-color-light);
|
||||
--vxe-table-menu-background-color: var(--el-bg-color-overlay);
|
||||
--vxe-loading-color: var(--el-color-primary);
|
||||
--vxe-loading-background-color: var(--el-mask-color);
|
||||
--vxe-table-validate-error-color: var(--el-color-danger);
|
||||
--vxe-toolbar-background-color: var(--el-bg-color);
|
||||
--vxe-toolbar-custom-active-background-color: var(--el-bg-color-overlay);
|
||||
--vxe-toolbar-panel-background-color: var(--el-bg-color-overlay);
|
||||
--vxe-pager-background-color: var(--el-bg-color);
|
||||
--vxe-modal-header-background-color: var(--el-bg-color);
|
||||
--vxe-modal-body-background-color: var(--el-bg-color);
|
||||
--vxe-modal-border-color: var(--el-border-color);
|
||||
--vxe-button-default-background-color: var(--el-bg-color-overlay);
|
||||
--vxe-input-background-color: var(--el-fill-color-blank);
|
||||
--vxe-input-panel-background-color: var(--el-fill-color-blank);
|
||||
--vxe-form-background-color: var(--el-bg-color);
|
||||
--vxe-form-validate-error-color: var(--el-color-danger);
|
||||
--vxe-select-option-hover-background-color: var(--el-bg-color-overlay);
|
||||
--vxe-select-panel-background-color: var(--el-bg-color);
|
||||
}
|
||||
|
||||
// VxeTable 自定义样式
|
||||
.vxe-grid {
|
||||
&--form-wrapper .vxe-form {
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
&--toolbar-wrapper .vxe-toolbar {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
&--pager-wrapper .vxe-pager {
|
||||
height: 70px;
|
||||
padding: 0 20px;
|
||||
|
||||
&--wrapper {
|
||||
@media screen and (width <= 768px) {
|
||||
.vxe-pager--total,
|
||||
.vxe-pager--sizes,
|
||||
.vxe-pager--jump,
|
||||
.vxe-pager--jump-prev,
|
||||
.vxe-pager--jump-next {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WangEditor 暗黑模式
|
||||
html.dark {
|
||||
--w-e-textarea-bg-color: var(--el-bg-color);
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<!-- 表格 -->
|
||||
<VxeGrid ref="xGrid" v-bind="gridOptions" v-on="gridEvents">
|
||||
<VxeGrid ref="xGridDom" v-bind="xGridOpt" v-on="xGridEvents">
|
||||
<!-- 搜索 -->
|
||||
<!-- <template #form-roles="{ data }">
|
||||
<el-select
|
||||
v-model="data.roles"
|
||||
multiple
|
||||
collapse-tags
|
||||
collapse-tags-tooltip
|
||||
placeholder="请选择角色"
|
||||
filterable
|
||||
<template #search-createTime="{ data, field }">
|
||||
<el-date-picker
|
||||
v-model="data[field]"
|
||||
class="w-full"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="截止日期"
|
||||
value-format="YYYY-MM-DD"
|
||||
:editable="false"
|
||||
clearable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</template> -->
|
||||
/>
|
||||
</template>
|
||||
<!-- 左侧按钮列表 -->
|
||||
<template #toolbar-btns>
|
||||
<VxeButton status="primary" icon="vxe-icon-add" @click="curd.onShowModal()">
|
||||
<VxeButton status="primary" icon="vxe-icon-add" @click="crudStore.onShowModal()">
|
||||
新增用户
|
||||
</VxeButton>
|
||||
<VxeButton status="danger" icon="vxe-icon-delete" @click="curd.onDelete()">
|
||||
<VxeButton status="danger" icon="vxe-icon-delete" @click="crudStore.onDelete()">
|
||||
批量删除
|
||||
</VxeButton>
|
||||
</template>
|
||||
@@ -62,33 +56,45 @@
|
||||
</template>
|
||||
<!-- 操作列 -->
|
||||
<template #column-operate="{ row }">
|
||||
<el-button link type="primary" @click="curd.onShowModal(row)">修改</el-button>
|
||||
<el-button link type="danger" @click="curd.onDelete(row)">删除</el-button>
|
||||
<el-button link type="primary" @click="crudStore.onShowModal(row)">修改</el-button>
|
||||
<el-button link type="danger" @click="crudStore.onDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</VxeGrid>
|
||||
|
||||
<!-- 弹窗 -->
|
||||
<VxeModal ref="xModal" v-bind="modalOptions">
|
||||
<VxeModal ref="xModalDom" v-bind="xModalOpt" v-on="xModalEvent">
|
||||
<!-- 表单 -->
|
||||
<VxeForm ref="xForm" v-bind="formOptions" />
|
||||
<VxeForm ref="xFormDom" v-bind="xFormOpt" />
|
||||
<!-- 底部按钮 -->
|
||||
<template #footer>
|
||||
<VxeButton content="取消" @click="xModalDom?.close()" />
|
||||
<VxeButton status="primary" content="确定" @click="crudStore.onSubmitForm()" />
|
||||
</template>
|
||||
</VxeModal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import "vxe-table/lib/style.css";
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import { reactive, onMounted, useTemplateRef } from "vue";
|
||||
import { configureVxeUI } from "@/plugins/vxe-table";
|
||||
import type { VxeGridInstance, VxeGridProps, VxeGridListeners } from "vxe-table";
|
||||
import { VxeGrid } from "vxe-table";
|
||||
import type {
|
||||
VxeFormInstance,
|
||||
VxeFormProps,
|
||||
VxeModalInstance,
|
||||
VxeModalProps,
|
||||
VxeModalListeners,
|
||||
} from "vxe-pc-ui";
|
||||
import {
|
||||
VXETable,
|
||||
VxeUI,
|
||||
VxeButton,
|
||||
VxeButtonGroup,
|
||||
VxeForm,
|
||||
VxeGrid,
|
||||
VxeInput,
|
||||
VxeModal,
|
||||
VxeSelect,
|
||||
} from "vxe-table";
|
||||
import { configureVxeTable } from "@/plugins/vxe-table";
|
||||
} from "vxe-pc-ui";
|
||||
|
||||
defineOptions({
|
||||
components: {
|
||||
@@ -102,24 +108,24 @@ defineOptions({
|
||||
},
|
||||
});
|
||||
|
||||
configureVxeTable();
|
||||
configureVxeUI();
|
||||
|
||||
const options = [
|
||||
{ label: "管理", value: "admin" },
|
||||
{ label: "用户", value: "user" },
|
||||
{ label: "访客", value: "guest" },
|
||||
];
|
||||
onMounted(() => {
|
||||
// 模拟异步加载数据
|
||||
setTimeout(() => {
|
||||
gridOptions!.formConfig!.items!.forEach((item) => {
|
||||
if (item.field === "roles") {
|
||||
item!.itemRender!.props!.options = options;
|
||||
}
|
||||
});
|
||||
const rolesItem = xGridDom.value
|
||||
?.getFormItems()
|
||||
.find((item) => item.field === "roles" && item.folding !== true);
|
||||
if (rolesItem) {
|
||||
rolesItem.itemRender!.props!.options = [
|
||||
{ label: "管理", value: "admin" },
|
||||
{ label: "用户", value: "user" },
|
||||
{ label: "访客", value: "guest" },
|
||||
];
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
// #region vxe-grid
|
||||
interface RowMeta {
|
||||
id: number;
|
||||
username: string;
|
||||
@@ -129,113 +135,27 @@ interface RowMeta {
|
||||
status: boolean;
|
||||
createTime: string;
|
||||
}
|
||||
const xGrid = ref<VxeGridInstance<RowMeta>>();
|
||||
const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
|
||||
// #region vxe-grid
|
||||
const xGridDom = useTemplateRef<VxeGridInstance<RowMeta>>("xGridDom");
|
||||
const xGridOpt = reactive<VxeGridProps<RowMeta>>({
|
||||
// 唯一标识(被某些特定的功能所依赖 比如storage)
|
||||
id: "user",
|
||||
// 保持原始值的状态,被某些功能所依赖,比如编辑状态、还原数据等(开启后影响性能,具体取决于数据量)
|
||||
keepSource: true,
|
||||
// 自动监听父元素的变化去重新计算表格
|
||||
autoResize: true,
|
||||
// 是否显示表尾
|
||||
showFooter: true,
|
||||
// 表尾数据(优先级比 footerMethod 高)
|
||||
// footerData: [
|
||||
// {
|
||||
// username: "-",
|
||||
// roles: "-",
|
||||
// phone: "-",
|
||||
// email: "-",
|
||||
// status: "启用/禁用",
|
||||
// createTime: "-",
|
||||
// },
|
||||
// ],
|
||||
// 表尾的数据获取方法,返回一个二维数组
|
||||
footerMethod({ columns, data }) {
|
||||
return [
|
||||
columns.map((column, columnIndex) => {
|
||||
if (columnIndex === 0 || column.field === undefined) {
|
||||
return "";
|
||||
} else if (column.field === "status") {
|
||||
return `启用 ${data.reduce((sum, row) => sum + (row.status ? 1 : 0), 0)} 条`;
|
||||
}
|
||||
return "-";
|
||||
}),
|
||||
];
|
||||
},
|
||||
// 列配置
|
||||
columns: [
|
||||
{ type: "checkbox", width: 60 },
|
||||
{
|
||||
type: "expand",
|
||||
width: 60,
|
||||
slots: {
|
||||
// 只对 type=expand 有效,自定义展开后的内容模板
|
||||
content: "column-expand",
|
||||
},
|
||||
},
|
||||
{ type: "seq", width: 60 },
|
||||
{ field: "id", title: "ID", visible: false },
|
||||
{ field: "username", title: "用户名" },
|
||||
{ field: "roles", title: "角色", slots: { default: "column-roles" } },
|
||||
{ field: "phone", title: "手机号" },
|
||||
{ field: "email", title: "邮箱" },
|
||||
{
|
||||
field: "status",
|
||||
title: "状态",
|
||||
sortable: true,
|
||||
filters: [
|
||||
{ label: "启用", value: true },
|
||||
{ label: "禁用", value: false },
|
||||
],
|
||||
// 数据筛选,只对 filters 有效,筛选是否允许多选
|
||||
filterMultiple: false,
|
||||
formatter({ cellValue }) {
|
||||
return cellValue === true ? "启用" : "禁用";
|
||||
},
|
||||
},
|
||||
{ field: "createTime", title: "创建时间", sortable: true },
|
||||
{
|
||||
title: "操作",
|
||||
width: "150px",
|
||||
fixed: "right",
|
||||
showOverflow: false,
|
||||
slots: {
|
||||
default: "column-operate",
|
||||
},
|
||||
},
|
||||
],
|
||||
// 列配置信息
|
||||
columnConfig: {
|
||||
// 每一列是否启用列宽拖动
|
||||
resizable: true,
|
||||
},
|
||||
// 自定义列配置项
|
||||
customConfig: {
|
||||
// 是否允许列选中
|
||||
checkMethod: ({ column }) => !["username"].includes(column.field),
|
||||
},
|
||||
// 复选框配置项
|
||||
checkboxConfig: {
|
||||
// 是否保留勾选状态(需要有 row-config.keyField)
|
||||
// reserve: true,
|
||||
},
|
||||
// 展开行配置项(不支持虚拟滚动)
|
||||
expandConfig: {
|
||||
// 展开列显示的字段名,可以直接显示在单元格中
|
||||
// labelField: "username",
|
||||
// 每次只能展开一行
|
||||
accordion: true,
|
||||
},
|
||||
// 行配置信息
|
||||
rowConfig: {
|
||||
// 自定义行数据唯一主键的字段名
|
||||
keyField: "id",
|
||||
// 当鼠标点击行时,是否要高亮当前行
|
||||
isCurrent: true,
|
||||
},
|
||||
// 表单配置项
|
||||
formConfig: {
|
||||
// 所有项的标题宽度
|
||||
titleWidth: 100,
|
||||
// 所有项的标题对齐方式
|
||||
titleAlign: "right",
|
||||
// NOTE: 表单数据 (不能和代理同时存在)
|
||||
// data: {},
|
||||
// 项配置
|
||||
items: [
|
||||
{
|
||||
span: 4,
|
||||
field: "username",
|
||||
title: "用户名",
|
||||
// 前缀配置项
|
||||
@@ -255,14 +175,13 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
clearable: true,
|
||||
placeholder: "请输入用户名",
|
||||
},
|
||||
defaultValue: "",
|
||||
},
|
||||
resetValue: "",
|
||||
},
|
||||
{
|
||||
span: 4,
|
||||
field: "roles",
|
||||
title: "角色",
|
||||
// 默认收起
|
||||
folding: true,
|
||||
itemRender: {
|
||||
name: "VxeSelect",
|
||||
props: {
|
||||
@@ -273,33 +192,42 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
options: [],
|
||||
placeholder: "请选择角色",
|
||||
},
|
||||
defaultValue: null,
|
||||
},
|
||||
resetValue: null,
|
||||
},
|
||||
{
|
||||
field: "createTime",
|
||||
title: "创建时间",
|
||||
// 默认收起
|
||||
folding: true,
|
||||
itemRender: {
|
||||
defaultValue: [],
|
||||
},
|
||||
resetValue: [],
|
||||
// 插槽
|
||||
slots: {
|
||||
// 自定义表单项
|
||||
default: "search-createTime",
|
||||
},
|
||||
},
|
||||
// {
|
||||
// span: 4,
|
||||
// field: "roles",
|
||||
// title: "角色",
|
||||
// // 默认收起
|
||||
// folding: true,
|
||||
// // 插槽
|
||||
// slots: {
|
||||
// // 自定义表单项
|
||||
// default: "form-roles",
|
||||
// },
|
||||
// },
|
||||
{
|
||||
span: 24,
|
||||
align: "left",
|
||||
collapseNode: true,
|
||||
itemRender: {
|
||||
name: "VxeButtonGroup",
|
||||
options: [
|
||||
{
|
||||
type: "submit",
|
||||
status: "primary",
|
||||
icon: "vxe-icon-search",
|
||||
content: "搜索",
|
||||
},
|
||||
{ type: "reset", icon: "vxe-icon-refresh", content: "重置" },
|
||||
],
|
||||
props: {
|
||||
options: [
|
||||
{
|
||||
type: "submit",
|
||||
status: "primary",
|
||||
icon: "vxe-icon-search",
|
||||
content: "搜索",
|
||||
},
|
||||
{ type: "reset", icon: "vxe-icon-refresh", content: "重置" },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -328,30 +256,212 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
importConfig: {},
|
||||
// 导出配置项
|
||||
exportConfig: {
|
||||
// 指定列
|
||||
// 默认选中文件类型
|
||||
type: "xlsx",
|
||||
// 可选文件类型列表
|
||||
types: ["xlsx", "csv", "html", "xml", "txt"],
|
||||
// 输出数据的方式
|
||||
mode: "current",
|
||||
// 输出数据的方式列表,如果为 all,则会通过 proxy-config.ajax.queryAll 获取数据之后进行导出
|
||||
modes: ["current", "selected"],
|
||||
// 指定列(列必须在表中显示,否则被忽略)
|
||||
columns: [{ field: "phone" }, { field: "email" }, { field: "status" }, { field: "createTime" }],
|
||||
// 列过滤方法,该函数的返回值用来决定是否过滤掉列
|
||||
columnFilterMethod({ column }) {
|
||||
return column.field !== undefined;
|
||||
},
|
||||
},
|
||||
// 打印配置项
|
||||
printConfig: {},
|
||||
printConfig: {
|
||||
// 自定义文档的 css 样式信息
|
||||
style: `
|
||||
.my-title {
|
||||
text-align: center;
|
||||
}`,
|
||||
// 在打印之前触发,可以通过返回自定义打印的内容
|
||||
beforePrintMethod: ({ content, options }) => {
|
||||
console.debug({ options });
|
||||
return `<h1 class="my-title">用户列表</h1>${content}`;
|
||||
},
|
||||
},
|
||||
// 缩放配置项
|
||||
zoomConfig: {
|
||||
// 是否允许通过按下 ESC 键还原
|
||||
escRestore: true,
|
||||
},
|
||||
// 自定义列配置项
|
||||
customConfig: {
|
||||
// NOTE: 是否启用 localStorage 本地保存,会将列操作状态保留在本地(需要有 id)
|
||||
storage: {
|
||||
// 启用显示/隐藏列状态缓存
|
||||
visible: true,
|
||||
// 启用冻结列状态缓存
|
||||
fixed: true,
|
||||
// 启用列宽状态缓存
|
||||
resizable: true,
|
||||
// 启用列顺序缓存(popup操作模式允许列排序)
|
||||
sort: false,
|
||||
},
|
||||
// 操作模式
|
||||
mode: "simple",
|
||||
// 列勾选之后是否实时同步
|
||||
immediate: false,
|
||||
// 是否允许自定义冻结列
|
||||
allowFixed: true,
|
||||
// 是否显示底部操作按钮
|
||||
showFooter: true,
|
||||
// NOTE: 计算公式绑定的单元格的插槽列不允许隐藏,否则公式会不生效
|
||||
// 是否允许列选中 返回值用来决定这一列的 checkbox 是否可以选中
|
||||
checkMethod: ({ column }) => !["username"].includes(column.field),
|
||||
// 是否显示列 返回值用来决定这一列的 checkbox 是否显示
|
||||
visibleMethod: ({ column }) => column.type === undefined,
|
||||
},
|
||||
// 列配置
|
||||
columns: [
|
||||
{ type: "checkbox", width: 60 },
|
||||
{
|
||||
type: "expand",
|
||||
width: 60,
|
||||
slots: {
|
||||
// 只对 type=expand 有效,自定义展开后的内容模板
|
||||
content: "column-expand",
|
||||
},
|
||||
},
|
||||
{ type: "seq", width: 60 },
|
||||
{ field: "id", title: "ID", visible: false },
|
||||
{ field: "username", title: "用户名" },
|
||||
{ field: "roles", title: "角色", slots: { default: "column-roles" } },
|
||||
{ field: "phone", title: "手机号" },
|
||||
{ field: "email", title: "邮箱" },
|
||||
{
|
||||
field: "status",
|
||||
title: "状态",
|
||||
filters: [
|
||||
{ label: "启用", value: true },
|
||||
{ label: "禁用", value: false },
|
||||
],
|
||||
// 数据筛选,只对 filters 有效,筛选是否允许多选
|
||||
filterMultiple: false,
|
||||
// 默认的渲染器配置项
|
||||
cellRender: {
|
||||
name: "VxeSwitch",
|
||||
props: {
|
||||
openLabel: "启用",
|
||||
closeLabel: "禁用",
|
||||
openValue: true,
|
||||
closeValue: false,
|
||||
},
|
||||
events: {
|
||||
change: ({ row, column }, { value }) => {
|
||||
crudStore.onModify(row.id, column.field, value);
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ field: "createTime", title: "创建时间", sortable: true },
|
||||
{
|
||||
field: "operate",
|
||||
title: "操作",
|
||||
width: "150px",
|
||||
fixed: "right",
|
||||
showOverflow: false,
|
||||
slots: {
|
||||
default: "column-operate",
|
||||
},
|
||||
},
|
||||
],
|
||||
// 行配置信息
|
||||
rowConfig: {
|
||||
// 自定义行数据唯一主键的字段名(默认自动生成 _X_ROW_KEY,刷新后值会变)
|
||||
keyField: "id",
|
||||
// 当鼠标点击行时,是否要高亮当前行
|
||||
isCurrent: true,
|
||||
// 当鼠标移到行时,是否要高亮当前行
|
||||
isHover: false,
|
||||
},
|
||||
// 列配置信息
|
||||
columnConfig: {
|
||||
// 每一列是否启用列宽调整
|
||||
resizable: true,
|
||||
// 每一列的最小宽度
|
||||
minWidth: 100,
|
||||
// 冻结列允许设置的最大数量(如果是分组,则一个分组算一个)
|
||||
maxFixedSize: 4,
|
||||
},
|
||||
// 复选框配置项
|
||||
checkboxConfig: {
|
||||
// 是否保留勾选状态(需要有 row-config.keyField)仅对分页切换时有效
|
||||
// reserve: true,
|
||||
// 高亮勾选行
|
||||
highlight: true,
|
||||
// 是否允许勾选 返回值用来决定这一行 checkbox 是否可以勾选
|
||||
checkMethod: ({ row }) => row.status === false,
|
||||
// 是否显示勾选 返回值用来决定这一行的 checkbox 是否显示
|
||||
visibleMethod: ({ row }) => row.status === false,
|
||||
},
|
||||
// 展开行配置项(不支持虚拟滚动)
|
||||
expandConfig: {
|
||||
// 展开列显示的字段名,可以直接显示在单元格中
|
||||
// labelField: "username",
|
||||
// 每次只能展开一行
|
||||
accordion: true,
|
||||
},
|
||||
// 设置所有内容过长时显示为省略号(如果是固定列建议设置该值,提升渲染速度)
|
||||
showOverflow: "tooltip",
|
||||
// 是否显示表尾
|
||||
showFooter: true,
|
||||
// 表尾数据(优先级比 footerMethod 高)
|
||||
// footerData: [
|
||||
// {
|
||||
// username: "-",
|
||||
// roles: "-",
|
||||
// phone: "-",
|
||||
// email: "-",
|
||||
// status: "启用/禁用",
|
||||
// createTime: "-",
|
||||
// },
|
||||
// ],
|
||||
// 表尾的数据获取方法,返回一个二维数组
|
||||
footerMethod({ columns, data }) {
|
||||
return [
|
||||
columns.map((column, columnIndex) => {
|
||||
if (columnIndex === 0 || column.field === undefined) {
|
||||
return "";
|
||||
} else if (column.field === "status") {
|
||||
return `启用 ${data.reduce((sum, row) => sum + (row.status ? 1 : 0), 0)} 条`;
|
||||
}
|
||||
return "-";
|
||||
}),
|
||||
];
|
||||
},
|
||||
// NOTE: 分页配置项(含 pager-config 才会启用分页)
|
||||
pagerConfig: {
|
||||
// 对齐方式
|
||||
align: "right",
|
||||
// 每页大小
|
||||
pageSize: 10,
|
||||
},
|
||||
// 筛选配置项
|
||||
filterConfig: {
|
||||
// 所有列是否使用服务端筛选
|
||||
remote: false,
|
||||
remote: true,
|
||||
},
|
||||
// 排序配置项
|
||||
sortConfig: {
|
||||
// 默认排序(只会在初始化时被触发一次)
|
||||
defaultSort: {
|
||||
// 列字段名
|
||||
field: "id",
|
||||
// 排序方式(asc升序 desc降序)
|
||||
order: "desc",
|
||||
},
|
||||
// 所有列是否使用服务端排序
|
||||
remote: false,
|
||||
remote: true,
|
||||
// 是否启用多列组合筛选
|
||||
multiple: false,
|
||||
// 只对 multiple 有效,是否按照先后触发顺序进行排序
|
||||
chronological: true,
|
||||
},
|
||||
// 分页配置项
|
||||
pagerConfig: {
|
||||
enabled: true,
|
||||
pageSize: 10,
|
||||
},
|
||||
// 数据代理配置项"
|
||||
proxyConfig: {
|
||||
// 是否自动加载查询数据
|
||||
@@ -373,8 +483,19 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
},
|
||||
ajax: {
|
||||
// 接收 Promise
|
||||
query: ({ page: { currentPage, pageSize } }) => {
|
||||
query: ({ page: { currentPage, pageSize }, form, filters, sort, sorts }) => {
|
||||
console.debug({ currentPage, pageSize, form, filters, sort, sorts });
|
||||
xGridOpt.loading = true;
|
||||
return new Promise<{ total: number; result: RowMeta[] }>((resolve) => {
|
||||
// 接口需要的参数
|
||||
// const params = {
|
||||
// page: currentPage,
|
||||
// limit: pageSize,
|
||||
// username: form.username,
|
||||
// roles: form.roles === null ? undefined : form.roles.join(","),
|
||||
// createTime: form.createTime.length > 0 ? form.createTime.join(",") : undefined,
|
||||
// };
|
||||
// 模拟异步加载数据
|
||||
setTimeout(() => {
|
||||
const list = [
|
||||
{
|
||||
@@ -477,6 +598,7 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
id: 640000197005230000,
|
||||
},
|
||||
];
|
||||
xGridOpt.loading = false;
|
||||
resolve({
|
||||
result: list.slice((currentPage - 1) * pageSize, currentPage * pageSize),
|
||||
total: list.length,
|
||||
@@ -487,32 +609,16 @@ const gridOptions = reactive<VxeGridProps<RowMeta>>({
|
||||
},
|
||||
},
|
||||
});
|
||||
const gridEvents: VxeGridListeners<RowMeta> = {
|
||||
// 只对 form-config 配置时有效,表单重置时会触发该事件
|
||||
formReset() {},
|
||||
const xGridEvents: VxeGridListeners<RowMeta> = {
|
||||
toggleRowExpand: ({ row, expanded }) => {
|
||||
console.debug("Toggle Row Expand", { row, expanded });
|
||||
},
|
||||
};
|
||||
// #endregion
|
||||
|
||||
// #region vxe-modal
|
||||
const xModal = ref();
|
||||
const modalOptions = reactive({
|
||||
// 窗口的标题
|
||||
title: "",
|
||||
// 是否允许点击遮罩层关闭窗口
|
||||
maskClosable: true,
|
||||
// 是否允许按 Esc 键关闭窗口
|
||||
escClosable: true,
|
||||
// 在窗口隐藏之前执行
|
||||
beforeHideMethod: () => {
|
||||
xForm.value?.clearValidate();
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
// #endregion
|
||||
|
||||
// #region vxe-form
|
||||
const xForm = ref();
|
||||
const formOptions = reactive({
|
||||
const xFormDom = useTemplateRef<VxeFormInstance>("xFormDom");
|
||||
const xFormOpt = reactive<VxeFormProps>({
|
||||
// 所有项的栅格占据的列数
|
||||
span: 24,
|
||||
// 所有项的标题宽度
|
||||
@@ -533,6 +639,7 @@ const formOptions = reactive({
|
||||
placeholder: "请输入",
|
||||
},
|
||||
},
|
||||
resetValue: "",
|
||||
},
|
||||
{
|
||||
field: "password",
|
||||
@@ -543,32 +650,7 @@ const formOptions = reactive({
|
||||
placeholder: "请输入",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
align: "right" as const,
|
||||
itemRender: {
|
||||
name: "$buttons",
|
||||
children: [
|
||||
{
|
||||
props: {
|
||||
content: "取消",
|
||||
},
|
||||
events: {
|
||||
click: () => xModal.value?.close(),
|
||||
},
|
||||
},
|
||||
{
|
||||
props: {
|
||||
type: "submit",
|
||||
content: "确定",
|
||||
status: "primary",
|
||||
},
|
||||
events: {
|
||||
click: () => curd.onSubmitForm(),
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
resetValue: "",
|
||||
},
|
||||
],
|
||||
/** 校验规则 */
|
||||
@@ -603,30 +685,127 @@ const formOptions = reactive({
|
||||
});
|
||||
// #endregion
|
||||
|
||||
const curd = {
|
||||
commitQuery: () => xGrid.value?.commitProxy("query"),
|
||||
// #region vxe-modal
|
||||
const xModalDom = useTemplateRef<VxeModalInstance>("xModalDom");
|
||||
const xModalOpt = reactive<VxeModalProps>({
|
||||
// 窗口的标题
|
||||
title: "",
|
||||
// 窗口的高度
|
||||
// height: 500,
|
||||
// 窗口宽度
|
||||
// width: "60%",
|
||||
// 窗口打开时自动最大化显示
|
||||
// fullscreen: true,
|
||||
// 标题是否标显示最大化与还原按钮
|
||||
showZoom: true,
|
||||
// 是否显示关闭按钮
|
||||
showClose: true,
|
||||
// 是否允许点击遮罩层关闭窗口
|
||||
maskClosable: true,
|
||||
// 是否允许按 Esc 键关闭窗口
|
||||
escClosable: true,
|
||||
// // 是否显示底部栏
|
||||
showFooter: true,
|
||||
// 在窗口关闭时销毁内容
|
||||
destroyOnClose: false,
|
||||
// 在窗口隐藏之前执行,可以返回 Error 阻止关闭,支持异步
|
||||
beforeHideMethod: ({ type }) => {
|
||||
console.debug("beforeHideMethod", type);
|
||||
xFormDom.value?.clearValidate();
|
||||
return Promise.resolve();
|
||||
},
|
||||
});
|
||||
const xModalEvent: VxeModalListeners = {
|
||||
// 显示时触发
|
||||
show: () => {
|
||||
console.debug("🚀 ~ show");
|
||||
},
|
||||
// 隐藏时触发
|
||||
hide: ({ type }) => {
|
||||
console.debug("🚀 ~ hide", type);
|
||||
const $form = xFormDom.value;
|
||||
if ($form) {
|
||||
$form.reset();
|
||||
$form.clearValidate();
|
||||
// 重置自定义表单项
|
||||
$form.getItems().forEach((item) => {
|
||||
if (item.slots?.default) {
|
||||
xFormOpt.data[item.field] = item.resetValue;
|
||||
}
|
||||
});
|
||||
// 重置表单数据(解决reset后数据不清空的问题)
|
||||
delete xFormOpt.data.id;
|
||||
// xFormOpt.data.id = 0
|
||||
}
|
||||
},
|
||||
};
|
||||
// #endregion
|
||||
|
||||
const crudStore = {
|
||||
/** 表单类型,true 表示修改,false 表示新增 */
|
||||
isUpdate: true,
|
||||
/** 加载表格数据 */
|
||||
commitQuery: () => xGridDom.value?.commitProxy("query"),
|
||||
/** 清空表格数据 */
|
||||
clearTable: () => xGridDom.value?.reloadData([]),
|
||||
/** 新增后是否跳入最后一页 */
|
||||
afterInsert: () => {
|
||||
const pager = xGridDom.value?.getProxyInfo()?.pager;
|
||||
if (pager) {
|
||||
const currentTotal = pager.currentPage * pager.pageSize;
|
||||
if (currentTotal === pager.total) {
|
||||
++pager.currentPage;
|
||||
}
|
||||
}
|
||||
},
|
||||
/** 删除后是否返回上一页 */
|
||||
afterDelete: () => {
|
||||
const tableData: RowMeta[] = xGridDom.value!.getData();
|
||||
const pager = xGridDom.value?.getProxyInfo()?.pager;
|
||||
if (pager && pager.currentPage > 1 && tableData.length === 1) {
|
||||
--pager.currentPage;
|
||||
}
|
||||
},
|
||||
/** 点击显示弹窗 */
|
||||
onShowModal: (row?: RowMeta) => {
|
||||
if (row) {
|
||||
modalOptions.title = "修改用户";
|
||||
crudStore.isUpdate = true;
|
||||
xModalOpt.title = "修改用户";
|
||||
xFormOpt.data = { ...row };
|
||||
} else {
|
||||
modalOptions.title = "新增用户";
|
||||
crudStore.isUpdate = false;
|
||||
xModalOpt.title = "新增用户";
|
||||
}
|
||||
xModal.value?.open();
|
||||
xModalDom.value?.open();
|
||||
},
|
||||
/** 确定并保存 */
|
||||
onSubmitForm: () => {
|
||||
VXETable.modal.message({
|
||||
content: "提交成功",
|
||||
status: "success",
|
||||
if (xModalOpt.loading) return;
|
||||
// 表单校验
|
||||
xFormDom.value?.validate((errMap) => {
|
||||
if (errMap) return;
|
||||
xModalOpt.loading = true;
|
||||
const callback = () => {
|
||||
xModalOpt.loading = false;
|
||||
xModalDom.value?.close();
|
||||
VxeUI.modal.message({ status: "success", content: "操作成功" });
|
||||
if (!crudStore.isUpdate) {
|
||||
crudStore.afterInsert();
|
||||
}
|
||||
crudStore.commitQuery();
|
||||
};
|
||||
// 模拟异步操作
|
||||
callback();
|
||||
});
|
||||
},
|
||||
/** 删除 */
|
||||
onDelete: (row?: RowMeta) => {
|
||||
let ids = [];
|
||||
if (row === undefined) {
|
||||
// 获取当前已选中的行数据
|
||||
const selected = xGrid.value?.getCheckboxRecords();
|
||||
const selected = xGridDom.value?.getCheckboxRecords();
|
||||
if (!selected || selected.length === 0) {
|
||||
VXETable.modal.message({
|
||||
VxeUI.modal.message({
|
||||
content: "请至少选择一条数据",
|
||||
status: "warning",
|
||||
});
|
||||
@@ -636,15 +815,153 @@ const curd = {
|
||||
} else {
|
||||
ids = [row.id];
|
||||
}
|
||||
VXETable.modal.confirm("确定要删除吗?").then((type) => {
|
||||
VxeUI.modal.confirm("确定要删除吗?").then((type) => {
|
||||
if (type === "confirm") {
|
||||
// 执行删除操作
|
||||
VXETable.modal.message({
|
||||
content: `已删除 ${ids.length} 条数据`,
|
||||
status: "success",
|
||||
});
|
||||
const callback = () => {
|
||||
// 执行删除操作
|
||||
VxeUI.modal.message({ status: "success", content: `已删除 ${ids.length} 条数据` });
|
||||
crudStore.afterDelete();
|
||||
crudStore.commitQuery();
|
||||
};
|
||||
// 模拟异步操作
|
||||
callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
onModify: (id: number, field: string, value: any) => {
|
||||
console.debug("🚀 ~ onModify", { id, field, value });
|
||||
},
|
||||
/** 更多自定义方法 */
|
||||
moreFn: () => {},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
:root {
|
||||
/* color */
|
||||
--vxe-ui-font-color: var(--el-text-color-regular);
|
||||
--vxe-ui-font-lighten-color: var(--el-text-color-primary);
|
||||
--vxe-ui-font-darken-color: var(--el-text-color-secondary);
|
||||
--vxe-ui-font-disabled-color: var(--el-text-color-disabled);
|
||||
|
||||
/*font status color*/
|
||||
--vxe-ui-font-primary-color: var(--el-color-primary);
|
||||
--vxe-ui-font-primary-lighten-color: var(--el-color-primary-light-3);
|
||||
--vxe-ui-font-primary-darken-color: var(--el-color-primary-dark-2);
|
||||
--vxe-ui-font-primary-disabled-color: var(--el-color-primary-light-5);
|
||||
|
||||
--vxe-ui-status-success-color: var(--el-color-success);
|
||||
--vxe-ui-status-info-color: var(--el-color-info);
|
||||
--vxe-ui-status-warning-color: var(--el-color-warning);
|
||||
--vxe-ui-status-danger-color: var(--el-color-danger);
|
||||
|
||||
--vxe-ui-status-success-lighten-color: var(--el-color-success-light-3);
|
||||
--vxe-ui-status-info-lighten-color: var(--el-color-info-light-3);
|
||||
--vxe-ui-status-warning-lighten-color: var(--el-color-warning-light-3);
|
||||
--vxe-ui-status-danger-lighten-color: var(--el-color-danger-light-3);
|
||||
|
||||
--vxe-ui-status-success-darken-color: var(--el-color-success-dark-2);
|
||||
--vxe-ui-status-info-darken-color: var(--el-color-info-dark-2);
|
||||
--vxe-ui-status-warning-darken-color: var(--el-color-warning-dark-2);
|
||||
--vxe-ui-status-danger-darken-color: var(--el-color-danger-dark-2);
|
||||
|
||||
--vxe-ui-status-success-disabled-color: var(--el-color-success-light-5);
|
||||
--vxe-ui-status-info-disabled-color: var(--el-color-info-light-5);
|
||||
--vxe-ui-status-warning-disabled-color: var(--el-color-warning-light-5);
|
||||
--vxe-ui-status-danger-disabled-color: var(--el-color-danger-light-5);
|
||||
|
||||
/*base*/
|
||||
--vxe-ui-base-popup-border-color: var(--el-border-color);
|
||||
|
||||
/* layout */
|
||||
--vxe-ui-layout-background-color: var(--el-bg-color);
|
||||
|
||||
/* input/radio/checkbox */
|
||||
--vxe-ui-input-border-color: var(--el-border-color);
|
||||
--vxe-ui-input-disabled-color: var(--el-text-color-disabled);
|
||||
--vxe-ui-input-disabled-background-color: var(--el-fill-color-light);
|
||||
--vxe-ui-input-placeholder-color: var(--el-text-color-placeholder);
|
||||
|
||||
/* table */
|
||||
--vxe-ui-table-border-color: var(--el-border-color-lighter);
|
||||
--vxe-ui-table-header-background-color: var(--el-bg-color);
|
||||
--vxe-ui-table-row-hover-background-color: var(--el-fill-color-light);
|
||||
--vxe-ui-table-row-current-background-color: var(--el-fill-color-light);
|
||||
--vxe-ui-table-row-hover-current-background-color: var(--el-fill-color-light);
|
||||
|
||||
/* loading */
|
||||
--vxe-ui-loading-color: var(--el-color-primary);
|
||||
--vxe-ui-loading-background-color: var(--el-mask-color);
|
||||
|
||||
/* modal */
|
||||
--vxe-ui-modal-header-background-color: var(--el-bg-color);
|
||||
|
||||
/* form */
|
||||
--vxe-ui-form-validate-error-color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
// VxeTable 自定义样式
|
||||
.vxe-grid {
|
||||
// 表单
|
||||
&--form-wrapper {
|
||||
.vxe-form {
|
||||
padding: 10px 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 工具栏
|
||||
&--toolbar-wrapper {
|
||||
.vxe-toolbar {
|
||||
padding: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 分页
|
||||
&--pager-wrapper {
|
||||
.vxe-pager {
|
||||
height: 70px;
|
||||
padding: 0 20px;
|
||||
&--wrapper {
|
||||
// 参考 Bootstrap 的响应式设计 WIDTH = 768
|
||||
@media screen and (max-width: 768px) {
|
||||
.vxe-pager--total,
|
||||
.vxe-pager--sizes,
|
||||
.vxe-pager--jump,
|
||||
.vxe-pager--jump-prev,
|
||||
.vxe-pager--jump-next {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.vxe-table {
|
||||
// 自定义列配置
|
||||
&-custom {
|
||||
&--body {
|
||||
min-height: 80px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 恢复 4.6 版本弹窗 loading 样式 */
|
||||
.vxe-modal--v46.vxe-modal--wrapper.is--loading {
|
||||
.vxe-modal--footer,
|
||||
.vxe-modal--header {
|
||||
&:before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
user-select: none;
|
||||
content: "";
|
||||
background-color: var(--vxe-ui-loading-background-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user