diff --git a/yudao-ui-admin-vue3/src/components/XTable/index.ts b/yudao-ui-admin-vue3/src/components/XTable/index.ts
new file mode 100644
index 000000000..4abe968eb
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/index.ts
@@ -0,0 +1,3 @@
+import XTable from './src/XTable.vue'
+
+export { XTable }
diff --git a/yudao-ui-admin-vue3/src/components/XTable/src/XTable.vue b/yudao-ui-admin-vue3/src/components/XTable/src/XTable.vue
new file mode 100644
index 000000000..75b0dc132
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/src/XTable.vue
@@ -0,0 +1,202 @@
+
+
+
+
+
+
+
+
+
diff --git a/yudao-ui-admin-vue3/src/components/XTable/src/style/dark.scss b/yudao-ui-admin-vue3/src/components/XTable/src/style/dark.scss
new file mode 100644
index 000000000..4e87c4b39
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/src/style/dark.scss
@@ -0,0 +1,81 @@
+// 修改样式变量
+//@import 'vxe-table/styles/variable.scss';
+
+/*font*/
+$vxe-font-color: #e5e7eb;
+// $vxe-font-size: 14px !default;
+// $vxe-font-size-medium: 16px !default;
+// $vxe-font-size-small: 14px !default;
+// $vxe-font-size-mini: 12px !default;
+
+/*color*/
+$vxe-primary-color: #409eff !default;
+$vxe-success-color: #67c23a !default;
+$vxe-info-color: #909399 !default;
+$vxe-warning-color: #e6a23c !default;
+$vxe-danger-color: #f56c6c !default;
+$vxe-disabled-color: #bfbfbf !default;
+$vxe-primary-disabled-color: #c0c4cc !default;
+
+/*loading*/
+$vxe-loading-color: $vxe-primary-color !default;
+$vxe-loading-background-color: #1d1e1f !default;
+$vxe-loading-z-index: 999 !default;
+
+/*icon*/
+$vxe-icon-font-family: Verdana, Arial, Tahoma !default;
+$vxe-icon-background-color: #e5e7eb !default;
+
+/*toolbar*/
+$vxe-toolbar-background-color: #1d1e1f !default;
+$vxe-toolbar-button-border: #dcdfe6 !default;
+$vxe-toolbar-custom-active-background-color: #d9dadb !default;
+$vxe-toolbar-panel-background-color: #e5e7eb !default;
+
+$vxe-table-font-color: #e5e7eb;
+$vxe-table-header-background-color: #1d1e1f;
+$vxe-table-body-background-color: #141414;
+$vxe-table-row-striped-background-color: #1d1d1d;
+$vxe-table-row-hover-background-color: #1d1e1f;
+$vxe-table-row-hover-striped-background-color: #1e1e1e;
+$vxe-table-footer-background-color: #1d1e1f;
+$vxe-table-row-current-background-color: #302d2d;
+$vxe-table-column-current-background-color: #302d2d;
+$vxe-table-column-hover-background-color: #302d2d;
+$vxe-table-row-hover-current-background-color: #302d2d;
+$vxe-table-row-checkbox-checked-background-color: #3e3c37 !default;
+$vxe-table-row-hover-checkbox-checked-background-color: #615a4a !default;
+$vxe-table-menu-background-color: #1d1e1f;
+$vxe-table-border-width: 1px !default;
+$vxe-table-border-color: #4c4d4f !default;
+$vxe-table-fixed-left-scrolling-box-shadow: 8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
+$vxe-table-fixed-right-scrolling-box-shadow: -8px 0px 10px -5px rgba(0, 0, 0, 0.12) !default;
+
+$vxe-form-background-color: #141414;
+
+/*pager*/
+$vxe-pager-background-color: #1d1e1f !default;
+$vxe-pager-perfect-background-color: #262727 !default;
+$vxe-pager-perfect-button-background-color: #a7a3a3 !default;
+
+$vxe-input-background-color: #141414;
+$vxe-input-border-color: #4c4d4f !default;
+
+$vxe-select-option-hover-background-color: #262626 !default;
+$vxe-select-panel-background-color: #141414 !default;
+$vxe-select-empty-color: #262626 !default;
+$vxe-optgroup-title-color: #909399 !default;
+
+/*button*/
+$vxe-button-default-background-color: #262626;
+$vxe-button-dropdown-panel-background-color: #141414;
+
+/*modal*/
+$vxe-modal-header-background-color: #141414;
+$vxe-modal-body-background-color: #141414;
+$vxe-modal-border-color: #3b3b3b;
+
+/*pulldown*/
+$vxe-pulldown-panel-background-color: #262626 !default;
+
+@import 'vxe-table/styles/index';
diff --git a/yudao-ui-admin-vue3/src/components/XTable/src/style/index.scss b/yudao-ui-admin-vue3/src/components/XTable/src/style/index.scss
new file mode 100644
index 000000000..350ce0c09
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/src/style/index.scss
@@ -0,0 +1,6 @@
+@import 'vxe-table/styles/variable.scss';
+@import 'vxe-table/styles/modules.scss';
+// @import './theme/light.scss';
+i {
+ border-color: initial;
+}
diff --git a/yudao-ui-admin-vue3/src/components/XTable/src/style/light.scss b/yudao-ui-admin-vue3/src/components/XTable/src/style/light.scss
new file mode 100644
index 000000000..f2f1309f4
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/src/style/light.scss
@@ -0,0 +1,16 @@
+// 修改样式变量
+// /*font*/
+// $vxe-font-size: 12px !default;
+// $vxe-font-size-medium: 16px !default;
+// $vxe-font-size-small: 14px !default;
+// $vxe-font-size-mini: 12px !default;
+/*color*/
+$vxe-primary-color: #409eff !default;
+$vxe-success-color: #67c23a !default;
+$vxe-info-color: #909399 !default;
+$vxe-warning-color: #e6a23c !default;
+$vxe-danger-color: #f56c6c !default;
+$vxe-disabled-color: #bfbfbf !default;
+$vxe-primary-disabled-color: #c0c4cc !default;
+
+@import 'vxe-table/styles/index.scss';
diff --git a/yudao-ui-admin-vue3/src/components/XTable/src/type.ts b/yudao-ui-admin-vue3/src/components/XTable/src/type.ts
new file mode 100644
index 000000000..83f6ca682
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/components/XTable/src/type.ts
@@ -0,0 +1,20 @@
+import { CrudSchema } from '@/hooks/web/useCrudSchemas'
+import type { VxeGridProps, VxeGridPropTypes } from 'vxe-table'
+
+export type XTableProps = VxeGridProps & {
+ allSchemas?: CrudSchema
+ getListApi?: Function
+ deleteApi?: Function
+ exportListApi?: Function
+ params?: any
+ pagination?: boolean | VxeGridPropTypes.PagerConfig
+ toolBar?: boolean | VxeGridPropTypes.ToolbarConfig
+ afterFetch?: Function
+}
+export type XColumns = VxeGridPropTypes.Columns
+
+export type VxeTableColumn = {
+ field: string
+ title?: string
+ children?: VxeTableColumn[]
+} & Recordable
diff --git a/yudao-ui-admin-vue3/src/components/index.ts b/yudao-ui-admin-vue3/src/components/index.ts
index 72facaa18..19b2aac69 100644
--- a/yudao-ui-admin-vue3/src/components/index.ts
+++ b/yudao-ui-admin-vue3/src/components/index.ts
@@ -4,6 +4,7 @@ import { Form } from '@/components/Form'
import { Table } from '@/components/Table'
import { Search } from '@/components/Search'
import { XModal } from '@/components/XModal'
+import { XTable } from '@/components/XTable'
import { XButton, XTextButton } from '@/components/XButton'
import { DictTag } from '@/components/DictTag'
import { ContentWrap } from '@/components/ContentWrap'
@@ -15,6 +16,7 @@ export const setupGlobCom = (app: App): void => {
app.component('Table', Table)
app.component('Search', Search)
app.component('XModal', XModal)
+ app.component('XTable', XTable)
app.component('XButton', XButton)
app.component('XTextButton', XTextButton)
app.component('DictTag', DictTag)
diff --git a/yudao-ui-admin-vue3/src/hooks/web/useXTable.ts b/yudao-ui-admin-vue3/src/hooks/web/useXTable.ts
new file mode 100644
index 000000000..8ac664bbe
--- /dev/null
+++ b/yudao-ui-admin-vue3/src/hooks/web/useXTable.ts
@@ -0,0 +1,28 @@
+import { ref, unref } from 'vue'
+import { XTableProps } from '@/components/XTable/src/type'
+
+export interface tableMethod {
+ reload: () => void
+ setProps: (props: XTableProps) => void
+}
+
+export function useXTable(props: XTableProps): [Function, tableMethod] {
+ const tableRef = ref>(null)
+
+ function register(instance) {
+ tableRef.value = instance
+ props && instance.setProps(props)
+ }
+ function getInstance(): tableMethod {
+ const table = unref(tableRef)
+ if (!table) {
+ console.error('表格实例不存在')
+ }
+ return table as tableMethod
+ }
+ const methods: tableMethod = {
+ reload: () => getInstance().reload(),
+ setProps: (props) => getInstance().setProps(props)
+ }
+ return [register, methods]
+}