diff --git a/README.en.md b/README.en.md index b5e917a78..5a543f98b 100644 --- a/README.en.md +++ b/README.en.md @@ -152,7 +152,7 @@ export default defineComponent({ [👉 View example](https://x-extends.github.io/vxe-table/#/table/base/basic) [👉 View API](https://x-extends.github.io/vxe-table/#/table/api) -## Donate +## Support the author If the open source software is helpful to you, you can scan the QR code below to support us.☕ diff --git a/README.md b/README.md index 970548063..6354c9338 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,7 @@ export default defineComponent({ [👉 查看演示](https://xuliangzhan_admin.gitee.io/vxe-table/#/table/base/basic) [👉 查看文档](https://xuliangzhan_admin.gitee.io/vxe-table/#/table/api) -## 捐赠 +## 支持作者 如果该开源软件对您有所帮助,可以扫下方二维码支持我们。☕ diff --git a/README.zh-TW.md b/README.zh-TW.md index 8620ca6b4..d01f817ce 100644 --- a/README.zh-TW.md +++ b/README.zh-TW.md @@ -152,7 +152,7 @@ export default defineComponent({ [👉 查看演示](https://xuliangzhan_admin.gitee.io/vxe-table/#/table/base/basic) [👉 查看檔案](https://xuliangzhan_admin.gitee.io/vxe-table/#/table/api) -## 捐贈 +## 支持作者 如果該開源軟件對您有所幫助,可以掃下方二維碼支持我們。☕ diff --git a/examples/api/table.ts b/examples/api/table.ts index d7c168014..c88239d2b 100644 --- a/examples/api/table.ts +++ b/examples/api/table.ts @@ -330,6 +330,24 @@ const exportDataAPI = [ defVal: '', list: [] }, + { + name: 'useStyle', + desc: '只对 type=html,xlsx 有效,支持带样式', + version: '', + type: 'Boolean', + enum: '', + defVal: 'false', + list: [] + }, + { + name: 'sheetMethod', + desc: '只对 type=xlsx 有效,该函数用于自定义工作簿的单元格', + version: '2.10.9', + type: '(params: { options, workbook, worksheet }) => void', + enum: '', + defVal: '', + list: [] + }, { name: 'exportMethod', desc: '只对 remote=true 有效,该函数用于自定义导出或服务端导出,返回 Promise', @@ -425,7 +443,7 @@ const importDataAPI = [ } ] -const printAPI = exportDataAPI.filter(item => !['filename', 'type', 'types', 'download', 'message', 'remote', 'exportMethod', 'beforeExportMethod', 'afterExportMethod'].includes(item.name)).concat([ +const printAPI = exportDataAPI.filter(item => !['filename', 'type', 'types', 'download', 'message', 'remote', 'sheetMethod', 'exportMethod', 'beforeExportMethod', 'afterExportMethod'].includes(item.name)).concat([ { name: 'content', desc: '自定义打印的内容', @@ -1680,6 +1698,15 @@ const apis = [ enum: '', defVal: '继承 setup.table.menuConfig', list: [ + { + name: 'enabled', + desc: '是否启用', + version: '', + type: 'boolean', + enum: '', + defVal: 'true', + list: [] + }, { name: 'header', desc: '表头的快捷菜单', diff --git a/examples/views/grid/Footer.vue b/examples/views/grid/Footer.vue index 518fafec9..9cecd4e7b 100644 --- a/examples/views/grid/Footer.vue +++ b/examples/views/grid/Footer.vue @@ -38,7 +38,7 @@ export default defineComponent({ { type: 'seq', width: 60 }, { field: 'name', title: 'app.body.label.name' }, { field: 'sex', title: 'app.body.label.sex' }, - { field: 'age', title: 'Age' }, + { field: 'age', title: 'Age', sortable: true }, { field: 'rate', title: 'Rate' } ], data: [ @@ -103,7 +103,7 @@ export default defineComponent({ { type: 'seq', width: 60 }, { field: 'name', title: 'app.body.label.name' }, { field: 'sex', title: 'app.body.label.sex' }, - { field: 'age', title: 'Age' }, + { field: 'age', title: 'Age', sortable: true }, { field: 'rate', title: 'Rate' } ], data: [ diff --git a/examples/views/grid/Group.vue b/examples/views/grid/Group.vue index 646a1b419..3e1e516a0 100644 --- a/examples/views/grid/Group.vue +++ b/examples/views/grid/Group.vue @@ -34,13 +34,13 @@ export default defineComponent({ title: '其他信息', children: [ { field: 'nickname', title: 'Nickname' }, - { field: 'age', title: 'Age' } + { field: 'age', title: 'Age', sortable: true } ] }, { field: 'sex', title: 'Sex' } ] }, - { field: 'address', title: 'Address', showOverflow: true } + { field: 'address', title: 'Address', sortable: true, showOverflow: true } ], data: [ { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' }, @@ -81,13 +81,13 @@ export default defineComponent({ title: '其他信息', children: [ { field: 'nickname', title: 'Nickname' }, - { field: 'age', title: 'Age' } + { field: 'age', title: 'Age', sortable: true } ] }, { field: 'sex', title: 'Sex' } ] }, - { field: 'address', title: 'Address', showOverflow: true } + { field: 'address', title: 'Address', sortable: true, showOverflow: true } ], data: [ { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' }, diff --git a/examples/views/start/I18n.vue b/examples/views/start/I18n.vue index f92adcb31..0286804f4 100644 --- a/examples/views/start/I18n.vue +++ b/examples/views/start/I18n.vue @@ -60,6 +60,11 @@ export default defineComponent({ i18n: (key, args) => i18n.global.t(key, args) }) + // 需要注意,如果没有使用 vxe-i18n,需要自行解析占位符 '{0}',例如: + // Vue.use(VXETable, { + // i18n: (key, args) => XEUtils.toFormatString(XEUtils.get(zhCN, key), args) + // }) + const app = createApp(App) app.use(i18n) diff --git a/examples/views/table/advanced/ManualFilter.vue b/examples/views/table/advanced/ManualFilter.vue index 1cf11d554..bd39d7afe 100644 --- a/examples/views/table/advanced/ManualFilter.vue +++ b/examples/views/table/advanced/ManualFilter.vue @@ -53,12 +53,6 @@ - -

{{ $t('app.body.button.showCode') }}

@@ -217,12 +211,6 @@ export default defineComponent({ - - `, ` diff --git a/examples/views/table/plugin/ExportPDF.vue b/examples/views/table/plugin/ExportPDF.vue index 12723b36e..0e745692d 100644 --- a/examples/views/table/plugin/ExportPDF.vue +++ b/examples/views/table/plugin/ExportPDF.vue @@ -75,7 +75,13 @@ export default defineComponent({ demo1.tableData = [ { orderNo: 'X02514645652', productNo: 'SX001', productName: 'XXX', realNum: 34, plannedNum: 20, describe: '' }, { orderNo: 'X02456765765', productNo: 'Sk001', productName: 'Mouse', realNum: 64, plannedNum: 80, describe: 'Account paid' }, - { orderNo: 'X05672556765', productNo: 'SX002', productName: 'Keyboard', realNum: 127, plannedNum: 90, describe: '' } + { orderNo: 'X05672556765', productNo: 'SX002', productName: 'Keyboard', realNum: 127, plannedNum: 88, describe: '' }, + { orderNo: 'X06768905676', productNo: 'SX003', productName: 'Keyboard', realNum: 13, plannedNum: 90, describe: '' }, + { orderNo: 'X05672556765', productNo: 'SX004', productName: 'Mouse', realNum: 89, plannedNum: 12, describe: '' }, + { orderNo: 'X00172556761', productNo: 'SX005', productName: 'Mouse', realNum: 46, plannedNum: 56, describe: '' }, + { orderNo: 'X05672556460', productNo: 'SX006', productName: 'Keyboard', realNum: 146, plannedNum: 3, describe: '' }, + { orderNo: 'X01872556499', productNo: 'SX007', productName: 'Keyboard', realNum: 47, plannedNum: 44, describe: '' }, + { orderNo: 'X77672556431', productNo: 'SX008', productName: 'Mouse', realNum: 126, plannedNum: 61, describe: '' } ] demo1.loading = false }, 100) @@ -148,7 +154,13 @@ export default defineComponent({ demo1.tableData = [ { orderNo: 'X02514645652', productNo: 'SX001', productName: 'XXX', realNum: 34, plannedNum: 20, describe: '' }, { orderNo: 'X02456765765', productNo: 'Sk001', productName: 'Mouse', realNum: 64, plannedNum: 80, describe: 'Account paid' }, - { orderNo: 'X05672556765', productNo: 'SX002', productName: 'Keyboard', realNum: 127, plannedNum: 90, describe: '' } + { orderNo: 'X05672556765', productNo: 'SX002', productName: 'Keyboard', realNum: 127, plannedNum: 88, describe: '' }, + { orderNo: 'X06768905676', productNo: 'SX003', productName: 'Keyboard', realNum: 13, plannedNum: 90, describe: '' }, + { orderNo: 'X05672556765', productNo: 'SX004', productName: 'Mouse', realNum: 89, plannedNum: 12, describe: '' }, + { orderNo: 'X00172556761', productNo: 'SX005', productName: 'Mouse', realNum: 46, plannedNum: 56, describe: '' }, + { orderNo: 'X05672556460', productNo: 'SX006', productName: 'Keyboard', realNum: 146, plannedNum: 3, describe: '' }, + { orderNo: 'X01872556499', productNo: 'SX007', productName: 'Keyboard', realNum: 47, plannedNum: 44, describe: '' }, + { orderNo: 'X77672556431', productNo: 'SX008', productName: 'Mouse', realNum: 126, plannedNum: 61, describe: '' } ] demo1.loading = false }, 100) diff --git a/examples/views/table/plugin/ExportXLSX.vue b/examples/views/table/plugin/ExportXLSX.vue index 29bda80ac..f92b6b41d 100644 --- a/examples/views/table/plugin/ExportXLSX.vue +++ b/examples/views/table/plugin/ExportXLSX.vue @@ -19,6 +19,7 @@ :loading="demo1.loading" :import-config="demo1.tableImport" :export-config="demo1.tableExport" + :merge-cells="demo1.mergeCells" :data="demo1.tableData"> @@ -63,7 +64,8 @@ export default defineComponent({ type: 'xlsx', // 自定义类型 types: ['xlsx', 'csv', 'html', 'xml', 'txt'] - } as VxeTablePropTypes.ExpandConfig + } as VxeTablePropTypes.ExpandConfig, + mergeCells: [] as VxeTablePropTypes.MergeCell[] }) const xTable = ref({} as VxeTableInstance) @@ -101,6 +103,10 @@ export default defineComponent({ { name: 'name8', role: 'role8', sex: '2', num: 9998, other: 10000000000000000, cardNo: '62221234018523736237' }, { name: 'name9', role: 'role9', sex: '1', num: 70000, other: 10000, cardNo: '62221230283686397412' } ] + demo1.mergeCells = [ + { row: 1, col: 1, rowspan: 2, colspan: 2 }, + { row: 4, col: 3, rowspan: 1, colspan: 3 } + ] demo1.loading = false }, 100) @@ -126,6 +132,7 @@ export default defineComponent({ :loading="demo1.loading" :import-config="demo1.tableImport" :export-config="demo1.tableExport" + :merge-cells="demo1.mergeCells" :data="demo1.tableData"> @@ -161,7 +168,8 @@ export default defineComponent({ type: 'xlsx', // 自定义类型 types: ['xlsx', 'csv', 'html', 'xml', 'txt'] - } as VxeTablePropTypes.ExpandConfig + } as VxeTablePropTypes.ExpandConfig, + mergeCells: [] as VxeTablePropTypes.MergeCell[] }) const xTable = ref({} as VxeTableInstance) @@ -199,6 +207,10 @@ export default defineComponent({ { name: 'name8', role: 'role8', sex: '2', num: 9998, other: 10000000000000000, cardNo: '62221234018523736237' }, { name: 'name9', role: 'role9', sex: '1', num: 70000, other: 10000, cardNo: '62221230283686397412' } ] + demo1.mergeCells = [ + { row: 1, col: 1, rowspan: 2, colspan: 2 }, + { row: 4, col: 3, rowspan: 1, colspan: 3 } + ] demo1.loading = false }, 100) diff --git a/examples/views/table/scroll/ScrollFullRows.vue b/examples/views/table/scroll/ScrollFullRows.vue index 9a026bd0a..2befccd61 100644 --- a/examples/views/table/scroll/ScrollFullRows.vue +++ b/examples/views/table/scroll/ScrollFullRows.vue @@ -100,6 +100,7 @@ export default defineComponent({ if (currSize < rowSize) { for (let i = currSize; i < rowSize; i++) { dataList.push({ + checked: false, attr0: 'attr0_row_' + i, attr1: 'attr1_row_' + i, attr2: 'attr2_row_' + i, @@ -229,6 +230,7 @@ export default defineComponent({ if (currSize < rowSize) { for (let i = currSize; i < rowSize; i++) { dataList.push({ + checked: false, attr0: 'attr0_row_' + i, attr1: 'attr1_row_' + i, attr2: 'attr2_row_' + i, diff --git a/examples/views/table/scroll/ScrollRows.vue b/examples/views/table/scroll/ScrollRows.vue index c99ddc378..1555a77d0 100644 --- a/examples/views/table/scroll/ScrollRows.vue +++ b/examples/views/table/scroll/ScrollRows.vue @@ -80,6 +80,7 @@ export default defineComponent({ if (currSize < rowSize) { for (let i = currSize; i < rowSize; i++) { dataList.push({ + checked: false, attr0: 'attr0_row_' + i, attr1: 'attr1_row_' + i, attr2: 'attr2_row_' + i, @@ -196,6 +197,7 @@ export default defineComponent({ if (currSize < rowSize) { for (let i = currSize; i < rowSize; i++) { dataList.push({ + checked: false, attr0: 'attr0_row_' + i, attr1: 'attr1_row_' + i, attr2: 'attr2_row_' + i, diff --git a/helper/vetur/attributes.json b/helper/vetur/attributes.json index 2194d59af..ee69cd99e 100644 --- a/helper/vetur/attributes.json +++ b/helper/vetur/attributes.json @@ -84,51 +84,51 @@ "description": "只对 edit-config 配置时有效,是否在编辑时高亮单元格边框(只支持部分)" }, "vxe-table/row-class-name": { - "type": "string | (({ row, rowindex, $rowindex }) => any)", + "type": "string | ((params: { row, rowindex, $rowindex }) => any)", "description": "给行附加 className" }, "vxe-table/cell-class-name": { - "type": "string | (({ row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", "description": "给单元格附加 className" }, "vxe-table/header-row-class-name": { - "type": "string | (({ $rowindex }) => any)", + "type": "string | ((params: { $rowindex }) => any)", "description": "给表头的行附加 className" }, "vxe-table/header-cell-class-name": { - "type": "string | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头的单元格附加 className" }, "vxe-table/footer-row-class-name": { - "type": "string | (({ $rowindex }) => any)", + "type": "string | ((params: { $rowindex }) => any)", "description": "给表尾的行附加 className" }, "vxe-table/footer-cell-class-name": { - "type": "string | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表尾的单元格附加 className" }, "vxe-table/cell-style": { - "type": "any | (({ row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", "description": "给单元格附加样式" }, "vxe-table/header-cell-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头单元格附加样式" }, "vxe-table/footer-cell-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表尾单元格附加样式" }, "vxe-table/row-style": { - "type": "any | (({ row, rowindex, $rowindex }) => any)", + "type": "any | ((params: { row, rowindex, $rowindex }) => any)", "description": "给行附加样式,也可以是函数" }, "vxe-table/header-row-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头行附加样式" }, "vxe-table/footer-row-style": { - "type": "any | (({ $rowindex }) => any)", + "type": "any | ((params: { $rowindex }) => any)", "description": "给表尾行附加样式" }, "vxe-table/show-footer": { @@ -136,24 +136,24 @@ "description": "是否显示表尾" }, "vxe-table/footer-method": { - "type": "({ columns, data }) => any[][]", + "type": "(params: { columns, data }) => any[][]", "description": "表尾的数据获取方法,返回一个二维数组" }, "vxe-table/merge-cells": { "type": "array<{ row: number, col: number, rowspan: number, colspan: number }>", - "description": "临时合并指定的单元格(不能用于树形结构、展开行,不建议用于固定列)" + "description": "临时合并指定的单元格 (不能用于展开行、树形结构,不建议用于固定列)" }, "vxe-table/merge-footer-items": { "type": "array<{ row: number, col: number, rowspan: number, colspan: number }>", - "description": "临时合并表尾(不能用于树形结构、展开行,不建议用于固定列)" + "description": "临时合并表尾 (不能用于展开行、树形结构,不建议用于固定列)" }, "vxe-table/span-method": { - "type": "({ row, rowindex, $rowindex, _rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", - "description": "自定义合并函数,返回计算后的值,不能用于虚拟滚动、树形结构、展开行、固定列" + "type": "(params: { row, rowindex, $rowindex, _rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", + "description": "自定义合并函数,返回计算后的值 (不能用于虚拟滚动、展开行,不建议用于固定列、树形结构)" }, "vxe-table/footer-span-method": { - "type": "({ $rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", - "description": "表尾合并行或列,返回计算后的值,不能用于虚拟滚动、树形结构、展开行、固定列" + "type": "(params: { $rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", + "description": "表尾合并行或列,返回计算后的值 (不能用于虚拟滚动、展开行,不建议用于固定列、树形结构)" }, "vxe-table/show-overflow": { "type": "boolean | string", @@ -183,10 +183,6 @@ "type": "boolean", "description": "保持原始值的状态,被某些功能所依赖,比如编辑状态、还原数据等(开启后影响性能,具体取决于数据量)" }, - "vxe-table/z-index": { - "type": "number", - "description": "自定义堆叠顺序(对于某些特殊场景,比如被遮挡时可能会用到)" - }, "vxe-table/column-config": { "type": "any", "description": "列的默认参数" @@ -240,8 +236,12 @@ "description": "快捷菜单配置项" }, "vxe-table/clip-config": { - "type": "object", - "description": "复制粘贴配置项" + "type": "any", + "description": "复制/粘贴配置项" + }, + "vxe-table/fnr-config": { + "type": "any", + "description": "查找/替换配置项" }, "vxe-table/mouse-config": { "type": "any", @@ -275,18 +275,6 @@ "type": "any", "description": "自定义列配置项" }, - "vxe-table/animat": { - "type": "boolean", - "description": "表格动画效果开关(关闭后视觉效果更快)" - }, - "vxe-table/cloak": { - "type": "boolean", - "description": "用于低性能的浏览器,可以设置为 true 来避免初始化渲染时的闪动" - }, - "vxe-table/delay-hover": { - "type": "number", - "description": "当表格发生拖动、滚动...等行为时,至少多少毫秒之后才允许触发 hover 事件" - }, "vxe-table/scroll-x": { "type": "any", "description": "横向虚拟滚动配置(注:当 tree-config 启用后自动关闭该功能)" @@ -416,7 +404,7 @@ "description": "给表尾的单元格附加 className" }, "vxe-table-column/formatter": { - "type": "(({ cellvalue, row, column }) => string) | any[] | string", + "type": "(({ cellvalue, row, column }) => any) | any[] | string", "description": "格式化显示内容" }, "vxe-table-column/seq-method": { @@ -428,7 +416,7 @@ "description": "是否允许列排序" }, "vxe-table-column/sort-by": { - "type": "string", + "type": "string | ((row) => string | number)", "description": "只对 sortable 有效,自定义排序的属性" }, "vxe-table-column/filters": { @@ -440,7 +428,7 @@ "description": "只对 filters 有效,筛选是否允许多选" }, "vxe-table-column/filter-method": { - "type": "({ value, row, column }) => boolean", + "type": "function", "description": "只对 filters 有效,列的筛选方法,该方法的返回值用来决定该行是否显示" }, "vxe-table-column/filter-render": { @@ -448,12 +436,12 @@ "description": "筛选渲染器配置项" }, "vxe-table-column/export-method": { - "type": "({ row, column }) => string", - "description": "自定义单元格数据导出方法,返回自定义的值" + "type": "function", + "description": "自定义单元格数据导出方法,该方法 Function({ row, column }) 的返回值将会被导出" }, "vxe-table-column/footer-export-method": { - "type": "({ items, _columnindex }) => string", - "description": "自定义表尾单元格数据导出方法,返回自定义的值" + "type": "function", + "description": "自定义表尾单元格数据导出方法,该方法 Function({ items, _columnIndex }) 的返回值将会被导出" }, "vxe-table-column/title-help": { "type": "any", @@ -485,7 +473,7 @@ }, "vxe-table-column/col-id": { "type": "string | number", - "description": "自定义列的唯一主键(注:非必要不需要设置,操作不正确将导致出现问题)" + "description": "自定义列的唯一主键(注:99%的场景不应该设置,操作不正确将导致出现问题)" }, "vxe-grid/id": { "type": "string", @@ -576,51 +564,51 @@ "description": "只对 edit-config 配置时有效,是否在编辑时高亮单元格边框(只支持部分)" }, "vxe-grid/row-class-name": { - "type": "string | (({ row, rowindex, $rowindex }) => any)", + "type": "string | ((params: { row, rowindex, $rowindex }) => any)", "description": "给行附加 className" }, "vxe-grid/cell-class-name": { - "type": "string | (({ row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", "description": "给单元格附加 className" }, "vxe-grid/header-row-class-name": { - "type": "string | (({ $rowindex }) => any)", + "type": "string | ((params: { $rowindex }) => any)", "description": "给表头的行附加 className" }, "vxe-grid/header-cell-class-name": { - "type": "string | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头的单元格附加 className" }, "vxe-grid/footer-row-class-name": { - "type": "string | (({ $rowindex }) => any)", + "type": "string | ((params: { $rowindex }) => any)", "description": "给表尾的行附加 className" }, "vxe-grid/footer-cell-class-name": { - "type": "string | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "string | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表尾的单元格附加 className" }, "vxe-grid/cell-style": { - "type": "any | (({ row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { row, rowindex, $rowindex, column, columnindex, $columnindex }) => any)", "description": "给单元格附加样式" }, "vxe-grid/header-cell-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头单元格附加样式" }, "vxe-grid/footer-cell-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表尾单元格附加样式" }, "vxe-grid/row-style": { - "type": "any | (({ row, rowindex, $rowindex }) => any)", + "type": "any | ((params: { row, rowindex, $rowindex }) => any)", "description": "给行附加样式,也可以是函数" }, "vxe-grid/header-row-style": { - "type": "any | (({ $rowindex, column, columnindex, $columnindex }) => any)", + "type": "any | ((params: { $rowindex, column, columnindex, $columnindex }) => any)", "description": "给表头行附加样式" }, "vxe-grid/footer-row-style": { - "type": "any | (({ $rowindex }) => any)", + "type": "any | ((params: { $rowindex }) => any)", "description": "给表尾行附加样式" }, "vxe-grid/show-footer": { @@ -628,24 +616,24 @@ "description": "是否显示表尾" }, "vxe-grid/footer-method": { - "type": "({ columns, data }) => any[][]", + "type": "(params: { columns, data }) => any[][]", "description": "表尾的数据获取方法,返回一个二维数组" }, "vxe-grid/merge-cells": { "type": "array<{ row: number, col: number, rowspan: number, colspan: number }>", - "description": "临时合并指定的单元格(不能用于树形结构、展开行,不建议用于固定列)" + "description": "临时合并指定的单元格 (不能用于展开行、树形结构,不建议用于固定列)" }, "vxe-grid/merge-footer-items": { "type": "array<{ row: number, col: number, rowspan: number, colspan: number }>", - "description": "临时合并表尾(不能用于树形结构、展开行,不建议用于固定列)" + "description": "临时合并表尾 (不能用于展开行、树形结构,不建议用于固定列)" }, "vxe-grid/span-method": { - "type": "({ row, rowindex, $rowindex, _rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", - "description": "自定义合并函数,返回计算后的值,不能用于虚拟滚动、树形结构、展开行、固定列" + "type": "(params: { row, rowindex, $rowindex, _rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", + "description": "自定义合并函数,返回计算后的值 (不能用于虚拟滚动、展开行,不建议用于固定列、树形结构)" }, "vxe-grid/footer-span-method": { - "type": "({ $rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", - "description": "表尾合并行或列,返回计算后的值,不能用于虚拟滚动、树形结构、展开行、固定列" + "type": "(params: { $rowindex, column, columnindex, $columnindex, _columnindex, data }) => { rowspan: number, colspan: number}", + "description": "表尾合并行或列,返回计算后的值 (不能用于虚拟滚动、展开行,不建议用于固定列、树形结构)" }, "vxe-grid/show-overflow": { "type": "boolean | string", @@ -675,10 +663,6 @@ "type": "boolean", "description": "保持原始值的状态,被某些功能所依赖,比如编辑状态、还原数据等(开启后影响性能,具体取决于数据量)" }, - "vxe-grid/z-index": { - "type": "number", - "description": "自定义堆叠顺序(对于某些特殊场景,比如被遮挡时可能会用到)" - }, "vxe-grid/column-config": { "type": "any", "description": "列的默认参数" @@ -732,8 +716,12 @@ "description": "快捷菜单配置项" }, "vxe-grid/clip-config": { - "type": "object", - "description": "复制粘贴配置项" + "type": "any", + "description": "复制/粘贴配置项" + }, + "vxe-grid/fnr-config": { + "type": "any", + "description": "查找/替换配置项" }, "vxe-grid/mouse-config": { "type": "any", @@ -767,18 +755,6 @@ "type": "any", "description": "自定义列配置项" }, - "vxe-grid/animat": { - "type": "boolean", - "description": "表格动画效果开关(关闭后视觉效果更快)" - }, - "vxe-grid/cloak": { - "type": "boolean", - "description": "用于低性能的浏览器,可以设置为 true 来避免初始化渲染时的闪动" - }, - "vxe-grid/delay-hover": { - "type": "number", - "description": "当表格发生拖动、滚动...等行为时,至少多少毫秒之后才允许触发 hover 事件" - }, "vxe-grid/scroll-x": { "type": "any", "description": "横向虚拟滚动配置(注:当 tree-config 启用后自动关闭该功能)" @@ -1140,12 +1116,12 @@ "description": "只对 type=date|time|datetime|week|month|year 有效,文本框是否允许输入" }, "vxe-input/disabled-method": { - "type": "({ date, type }) => boolean", - "description": "只对 type=date|datetime|week|month|year 有效,该方法的返回值用来决定该日期是否允许选中" + "type": "function", + "description": "只对 type=date|datetime|week|month|year 有效,该方法 Function({ date, type }) 的返回值用来决定该日期是否允许选中" }, "vxe-input/festival-method": { - "type": "({ date, type }) => any", - "description": "只对 type=date|datetime|week|month|year 有效,该方法用于返回对应日期显示的节日" + "type": "function", + "description": "只对 type=date|datetime|week|month|year 有效,该方法 Function({ date, type }) 用于返回对应日期显示的节日" }, "vxe-input/transfer": { "type": "boolean", @@ -1304,7 +1280,7 @@ "description": "是否显示" }, "vxe-tooltip/content": { - "type": "string | number", + "type": "string", "description": "显示内容" }, "vxe-tooltip/trigger": { @@ -1357,7 +1333,7 @@ }, "vxe-modal/status": { "type": "string", - "description": "confirm" + "description": "只对 type=alert | confirm | message 有效,消息状态" }, "vxe-modal/class-name": { "type": "string", @@ -1407,6 +1383,10 @@ "type": "boolean", "description": "是否允许按 Esc 键关闭窗口" }, + "vxe-modal/show-zoom": { + "type": "boolean", + "description": "是否允许窗口最大化与还原" + }, "vxe-modal/resize": { "type": "boolean", "description": "是否允许拖动调整窗口大小" @@ -1472,7 +1452,7 @@ "description": "是否启用 localStorage 本地保存,会将窗口拖动的状态保存到本地(需要有 id)" }, "vxe-modal/before-hide-method": { - "type": "({ type }) => error | promise", + "type": "function/promise", "description": "在窗口隐藏之前执行,可以返回 Error 阻止关闭,支持异步" }, "vxe-form/data": { @@ -1521,7 +1501,7 @@ }, "vxe-form/prevent-submit": { "type": "boolean", - "description": "禁用默认提交方式,禁用后配合 validate() 方法可以更加自由的控制提交逻辑" + "description": "是否禁用默认的回车提交方式,禁用后配合 validate() 方法可以更加自由的控制提交逻辑" }, "vxe-form/valid-config": { "type": "any", @@ -1556,7 +1536,7 @@ "description": "是否可视" }, "vxe-form-item/visible-method": { - "type": "({ data }) => boolean", + "type": "function", "description": "该方法的返回值用来决定该项是否显示" }, "vxe-form-item/folding": { diff --git a/helper/vetur/tags.json b/helper/vetur/tags.json index eb319879a..31f879b25 100644 --- a/helper/vetur/tags.json +++ b/helper/vetur/tags.json @@ -47,7 +47,6 @@ "row-key", "row-id", "keep-source", - "z-index", "column-config", "seq-config", "sort-config", @@ -62,6 +61,7 @@ "tree-config", "menu-config", "clip-config", + "fnr-config", "mouse-config", "keyboard-config", "edit-config", @@ -70,9 +70,6 @@ "empty-text", "empty-render", "custom-config", - "animat", - "cloak", - "delay-hover", "scroll-x", "scroll-y", "params" @@ -188,7 +185,6 @@ "row-key", "row-id", "keep-source", - "z-index", "column-config", "seq-config", "sort-config", @@ -203,6 +199,7 @@ "tree-config", "menu-config", "clip-config", + "fnr-config", "mouse-config", "keyboard-config", "edit-config", @@ -211,9 +208,6 @@ "empty-text", "empty-render", "custom-config", - "animat", - "cloak", - "delay-hover", "scroll-x", "scroll-y", "params", @@ -453,6 +447,7 @@ "mask", "mask-closable", "esc-closable", + "show-zoom", "resize", "duration", "width", diff --git a/package.json b/package.json index b3c12661e..ba6b99d0c 100644 --- a/package.json +++ b/package.json @@ -42,13 +42,14 @@ "@vue/eslint-config-typescript": "^5.0.2", "ant-design-vue": "^2.0.0-rc.5", "core-js": "^3.6.5", - "element-plus": "^1.0.1-beta.8", + "element-plus": "^1.0.1-beta.11", "eslint": "^6.7.2", "eslint-plugin-import": "^2.20.2", "eslint-plugin-node": "^11.1.0", "eslint-plugin-promise": "^4.2.1", "eslint-plugin-standard": "^4.0.0", "eslint-plugin-vue": "^7.0.0-0", + "exceljs": "^4.2.0", "font-awesome": "^4.7.0", "gulp": "^4.0.2", "gulp-autoprefixer": "^6.1.0", diff --git a/packages/export/src/export-panel.ts b/packages/export/src/export-panel.ts index 70d14d76d..ed8607dd0 100644 --- a/packages/export/src/export-panel.ts +++ b/packages/export/src/export-panel.ts @@ -38,7 +38,7 @@ export default defineComponent({ const computeShowSheet = computed(() => { const { defaultOptions } = props - return ['html', 'xml', 'xlsx'].indexOf(defaultOptions.type) > -1 + return ['html', 'xml', 'xlsx', 'pdf'].indexOf(defaultOptions.type) > -1 }) const computeSupportMerge = computed(() => { @@ -46,6 +46,11 @@ export default defineComponent({ return !defaultOptions.original && (storeData.isPrint || ['html', 'xlsx'].indexOf(defaultOptions.type) > -1) }) + const computeSupportStyle = computed(() => { + const { defaultOptions } = props + return !defaultOptions.original && ['xlsx'].indexOf(defaultOptions.type) > -1 + }) + const handleOptionCheck = (column: any) => { const { storeData } = props const matchObj = XEUtils.findTree(storeData.columns as any[], item => item === column) @@ -106,7 +111,9 @@ export default defineComponent({ const { storeData, defaultOptions } = props const checkedAll = computeCheckedAll.value const columns = XEUtils.searchTree(storeData.columns, (column: any) => column.checked, { children: 'children', mapChildren: 'childNodes', original: true }) - return Object.assign({ columns }, defaultOptions, { isMerge: checkedAll ? defaultOptions.isMerge : false }) + return Object.assign({ columns }, defaultOptions, { + isMerge: checkedAll ? defaultOptions.isMerge : false + }) } const printEvent = () => { @@ -151,6 +158,7 @@ export default defineComponent({ const checkedAll = computeCheckedAll.value const showSheet = computeShowSheet.value const supportMerge = computeSupportMerge.value + const supportStyle = computeSupportStyle.value XEUtils.eachTree(storeData.columns, (column: any) => { const colTitle = UtilTools.formatText(column.getTitle(), 1) const isColGroup = column.children && column.children.length @@ -364,6 +372,15 @@ export default defineComponent({ defaultOptions.isMerge = value } }), + isPrint ? createCommentVNode() : h(VxeCheckboxConstructor, { + modelValue: supportStyle ? defaultOptions.useStyle : false, + disabled: !supportStyle, + title: GlobalConfig.i18n('vxe.export.expUseStyleTitle'), + content: GlobalConfig.i18n('vxe.export.expOptUseStyle'), + 'onUpdate:modelValue' (value: any) { + defaultOptions.useStyle = value + } + }), h(VxeCheckboxConstructor, { modelValue: hasTree ? defaultOptions.isAllExpand : false, disabled: !hasTree, diff --git a/packages/export/src/hook.ts b/packages/export/src/hook.ts index a91f53a44..1ae5b6493 100644 --- a/packages/export/src/hook.ts +++ b/packages/export/src/hook.ts @@ -87,6 +87,10 @@ function toTableBorder (border: any) { return 'default' } +function getBooleanValue (cellValue: any) { + return cellValue === 'TRUE' || cellValue === 'true' || cellValue === true +} + function getHeaderTitle (opts: any, column: any) { return (opts.original ? column.property : column.getTitle()) || '' } @@ -296,6 +300,10 @@ const tableExportHook: VxeGlobalHooksHandles.HookOptions = { return seqMethod ? seqMethod({ row, rowIndex, column, columnIndex }) : (seqOpts.startIndex + rowIndex + 1) } + const toBooleanValue = (cellValue: any) => { + return XEUtils.isBoolean(cellValue) ? (cellValue ? 'TRUE' : 'FALSE') : cellValue + } + const getLabelData = (opts: any, columns: any[], datas: any[]) => { const { isAllExpand } = opts const { treeConfig } = props @@ -337,12 +345,12 @@ const tableExportHook: VxeGlobalHooksHandles.HookOptions = { cellValue = getSeq(row, rowIndex, column, columnIndex) break case 'checkbox': - cellValue = $xetable.isCheckedByCheckboxRow(row) + cellValue = toBooleanValue($xetable.isCheckedByCheckboxRow(row)) item._checkboxLabel = checkboxOpts.labelField ? XEUtils.get(row, checkboxOpts.labelField) : '' item._checkboxDisabled = checkboxOpts.checkMethod && !checkboxOpts.checkMethod({ row }) break case 'radio': - cellValue = $xetable.isCheckedByRadioRow(row) + cellValue = toBooleanValue($xetable.isCheckedByRadioRow(row)) item._radioLabel = radioOpts.labelField ? XEUtils.get(row, radioOpts.labelField) : '' item._radioDisabled = radioOpts.checkMethod && !radioOpts.checkMethod({ row }) break @@ -392,12 +400,12 @@ const tableExportHook: VxeGlobalHooksHandles.HookOptions = { cellValue = getSeq(row, rowIndex, column, columnIndex) break case 'checkbox': - cellValue = $xetable.isCheckedByCheckboxRow(row) + cellValue = toBooleanValue($xetable.isCheckedByCheckboxRow(row)) item._checkboxLabel = checkboxOpts.labelField ? XEUtils.get(row, checkboxOpts.labelField) : '' item._checkboxDisabled = checkboxOpts.checkMethod && !checkboxOpts.checkMethod({ row }) break case 'radio': - cellValue = $xetable.isCheckedByRadioRow(row) + cellValue = toBooleanValue($xetable.isCheckedByRadioRow(row)) item._radioLabel = radioOpts.labelField ? XEUtils.get(row, radioOpts.labelField) : '' item._radioDisabled = radioOpts.checkMethod && !radioOpts.checkMethod({ row }) break @@ -579,16 +587,16 @@ const tableExportHook: VxeGlobalHooksHandles.HookOptions = { } classNames.push('vxe-table--tree-node') if (column.type === 'radio') { - return `
${treeIcon}
${item._radioLabel}
` + return `
${treeIcon}
${item._radioLabel}
` } else if (column.type === 'checkbox') { - return `
${treeIcon}
${item._checkboxLabel}
` + return `
${treeIcon}
${item._checkboxLabel}
` } return `
${treeIcon}
${cellValue}
` } if (column.type === 'radio') { - return `
${item._radioLabel}
` + return `
${item._radioLabel}
` } else if (column.type === 'checkbox') { - return `
${item._checkboxLabel}
` + return `
${item._checkboxLabel}
` } return `
${formatText(cellValue, true)}
` }).join('') + '' @@ -624,9 +632,9 @@ const tableExportHook: VxeGlobalHooksHandles.HookOptions = { classNames.push(`col--${cellAlign}`) } if (column.type === 'radio') { - return `
${item._radioLabel}
` + return `
${item._radioLabel}
` } else if (column.type === 'checkbox') { - return `
${item._checkboxLabel}
` + return `
${item._checkboxLabel}
` } return `
${formatText(cellValue, true)}
` }).join('') + '' diff --git a/packages/input/src/input.ts b/packages/input/src/input.ts index e2f42869f..30f3e4dcc 100644 --- a/packages/input/src/input.ts +++ b/packages/input/src/input.ts @@ -538,8 +538,9 @@ export default defineComponent({ inputMethods.dispatchEvent(evnt.type, { value: inputValue }, evnt) } - const emitUpdate = (value: VxeInputPropTypes.ModelValue, evnt: Event | { type: string }) => { + const emitModel = (value: VxeInputPropTypes.ModelValue, evnt: Event | { type: string }) => { reactData.inputValue = value + inputMethods.dispatchEvent('input', { value }, evnt) emit('update:modelValue', value) if (XEUtils.toString(props.modelValue) !== value) { inputMethods.dispatchEvent('change', { value }, evnt) @@ -550,12 +551,12 @@ export default defineComponent({ const isDatePickerType = computeIsDatePickerType.value const { immediate } = props reactData.inputValue = value - if (immediate) { - if (!isDatePickerType) { - emitUpdate(value, evnt) + if (!isDatePickerType) { + if (immediate) { + emitModel(value, evnt) } + inputMethods.dispatchEvent('input', { value }, evnt) } - inputMethods.dispatchEvent('input', { value }, evnt) } const inputEvent = (evnt: Event & { type: 'input' }) => { @@ -569,7 +570,7 @@ export default defineComponent({ if (immediate) { triggerEvent(evnt) } else { - emitUpdate(reactData.inputValue, evnt) + emitModel(reactData.inputValue, evnt) } } @@ -612,7 +613,7 @@ export default defineComponent({ const { disabled } = props if (!disabled) { if (DomTools.hasClass(evnt.currentTarget, 'is--clear')) { - emitUpdate('', evnt) + emitModel('', evnt) clearValueEvent(evnt, '') } else { const { inputValue } = reactData @@ -669,7 +670,7 @@ export default defineComponent({ if (inputValue) { const validValue = XEUtils.toFixed(XEUtils.floor(inputValue, digitsValue), digitsValue) if (inputValue !== validValue) { - emitUpdate(validValue, { type: 'init' }) + emitModel(validValue, { type: 'init' }) } } } @@ -710,7 +711,7 @@ export default defineComponent({ const inpVal = XEUtils.toDateString(date, dateValueFormat) dateCheckMonth(date) if (!XEUtils.isEqual(modelValue, inpVal)) { - emitUpdate(inpVal, { type: 'update' }) + emitModel(inpVal, { type: 'update' }) } } @@ -731,7 +732,7 @@ export default defineComponent({ } else if (!vaildMaxNum(inpVal)) { inpVal = max } - emitUpdate(getNumberValue(inpVal), { type: 'check' }) + emitModel(getNumberValue(inpVal), { type: 'check' }) } } else if (isDatePickerType) { inpVal = inputValue @@ -745,7 +746,7 @@ export default defineComponent({ if (type === 'time') { inpVal = XEUtils.toDateString(inpVal, dateLabelFormat) if (inputValue !== inpVal) { - emitUpdate(inpVal, { type: 'check' }) + emitModel(inpVal, { type: 'check' }) } reactData.inputValue = inpVal } else { @@ -764,7 +765,7 @@ export default defineComponent({ dateRevert() } } else { - emitUpdate('', { type: 'check' }) + emitModel('', { type: 'check' }) } } } @@ -774,7 +775,7 @@ export default defineComponent({ const { immediate } = props const { inputValue } = reactData if (!immediate) { - emitUpdate(inputValue, evnt) + emitModel(inputValue, evnt) } afterCheckValue() if (!reactData.visiblePanel) { @@ -1317,8 +1318,11 @@ export default defineComponent({ } const datePickerOpenEvent = (evnt: Event) => { - evnt.preventDefault() - showPanel() + const { readonly } = props + if (!readonly) { + evnt.preventDefault() + showPanel() + } } const clickEvent = (evnt: Event & { type: 'click' }) => { @@ -1384,8 +1388,7 @@ export default defineComponent({ if (visiblePanel) { dateOffsetEvent(evnt) } else if (isUpArrow || isDwArrow) { - evnt.preventDefault() - showPanel() + datePickerOpenEvent(evnt) } } } @@ -1398,7 +1401,7 @@ export default defineComponent({ hidePanel() } } else if (isActivated) { - showPanel() + datePickerOpenEvent(evnt) } } } else if (isPgUp || isPgDn) { diff --git a/packages/locale/lang/en-US.ts b/packages/locale/lang/en-US.ts index eeee61e3d..4221b980e 100644 --- a/packages/locale/lang/en-US.ts +++ b/packages/locale/lang/en-US.ts @@ -207,10 +207,12 @@ export default { expFooterTitle: 'Do you need the footer table', expOptColgroup: 'Group header', expColgroupTitle: 'If it exists, headers with grouping structure are supported', - expOptMerge: 'Cell merge', + expOptMerge: 'Merge', expMergeTitle: 'If it exists, cells with merged structures are supported', - expOptAllExpand: 'Expand all nodes', + expOptAllExpand: 'Expand nodes', expAllExpandTitle: 'If it exists, all data with tree structure can be expanded', + expOptUseStyle: 'Styles', + expUseStyleTitle: 'If it exists, cells with styles are supported', expOptOriginal: 'Source data', expOriginalTitle: 'If it is source data, import into the table is supported', expPrint: 'Print', diff --git a/packages/locale/lang/ja-JP.ts b/packages/locale/lang/ja-JP.ts index 87df6375c..7e8750354 100644 --- a/packages/locale/lang/ja-JP.ts +++ b/packages/locale/lang/ja-JP.ts @@ -207,10 +207,12 @@ export default { expFooterTitle: 'フッターをエクスポート', expOptColgroup: '分组表头', expColgroupTitle: '如果存在,则支持带有分组结构的表头', - expOptMerge: '单元格合并', + expOptMerge: '合并', expMergeTitle: '如果存在,则支持带有合并结构的单元格', - expOptAllExpand: '展开所有层级', + expOptAllExpand: '展开层级', expAllExpandTitle: '如果存在,则支持将带有层级结构的数据全部展开', + expOptUseStyle: '样式', + expUseStyleTitle: '如果存在,则支持带样式的单元格', expOptOriginal: 'ソースデータ', expOriginalTitle: '如果为源数据,则支持导入到表格中', expPrint: '印刷', diff --git a/packages/locale/lang/zh-CN.ts b/packages/locale/lang/zh-CN.ts index cbc61055b..139553631 100644 --- a/packages/locale/lang/zh-CN.ts +++ b/packages/locale/lang/zh-CN.ts @@ -207,10 +207,12 @@ export default { expFooterTitle: '是否需要表尾', expOptColgroup: '分组表头', expColgroupTitle: '如果存在,则支持带有分组结构的表头', - expOptMerge: '单元格合并', + expOptMerge: '合并', expMergeTitle: '如果存在,则支持带有合并结构的单元格', - expOptAllExpand: '展开所有层级', + expOptAllExpand: '展开层级', expAllExpandTitle: '如果存在,则支持将带有层级结构的数据全部展开', + expOptUseStyle: '样式', + expUseStyleTitle: '如果存在,则支持带样式的单元格', expOptOriginal: '源数据', expOriginalTitle: '如果为源数据,则支持导入到表格中', expPrint: '打印', diff --git a/packages/locale/lang/zh-TC.ts b/packages/locale/lang/zh-TC.ts index 29130e963..9984e4964 100644 --- a/packages/locale/lang/zh-TC.ts +++ b/packages/locale/lang/zh-TC.ts @@ -207,10 +207,12 @@ export default { expFooterTitle: '是否需要表尾', expOptColgroup: '分组表头', expColgroupTitle: '如果存在,則支持帶有分組結構的表頭', - expOptMerge: '儲存格合併', + expOptMerge: '合併', expMergeTitle: '如果存在,則支持帶有合併結構的儲存格', - expOptAllExpand: '展開所有層級', + expOptAllExpand: '展開層級', expAllExpandTitle: '如果存在,則支持將帶有樹結構的數據全部展開', + expOptUseStyle: '樣式', + expUseStyleTitle: '如果存在,則支持帶樣式的儲存格', expOptOriginal: '源數據', expOriginalTitle: '如果為源數據,則支持導入到表格中', expPrint: '列印', diff --git a/packages/menu/src/hooks.ts b/packages/menu/src/hooks.ts index 2b9e9bcdc..f33a0af02 100644 --- a/packages/menu/src/hooks.ts +++ b/packages/menu/src/hooks.ts @@ -11,7 +11,7 @@ const tableMenuHook: VxeGlobalHooksHandles.HookOptions = { setupTable ($xetable) { const { xID, props, reactData, internalData, refMaps, computeMaps } = $xetable const { refElem, refTableFilter, refTableMenu } = refMaps - const { computeMouseOpts, computeMenuOpts } = computeMaps + const { computeMouseOpts, computeIsMenu, computeMenuOpts } = computeMaps let menuMethods = {} as TableMenuMethods let menuPrivateMethods = {} as TableMenuPrivateMethods @@ -21,6 +21,7 @@ const tableMenuHook: VxeGlobalHooksHandles.HookOptions = { */ const openContextMenu = (evnt: any, type: 'header' | 'body' | 'footer', params: any) => { const { ctxMenuStore } = reactData + const isMenu = computeIsMenu.value const menuOpts = computeMenuOpts.value const config = menuOpts[type] const visibleMethod = menuOpts.visibleMethod @@ -28,7 +29,7 @@ const tableMenuHook: VxeGlobalHooksHandles.HookOptions = { const { options, disabled } = config if (disabled) { evnt.preventDefault() - } else if (options && options.length) { + } else if (isMenu && options && options.length) { params.options = options $xetable.preventEvent(evnt, 'event.showMenu', params, null, () => { if (!visibleMethod || visibleMethod(params)) { diff --git a/packages/table/src/table.ts b/packages/table/src/table.ts index 19d68fc3e..2943933f8 100644 --- a/packages/table/src/table.ts +++ b/packages/table/src/table.ts @@ -210,6 +210,7 @@ export default defineComponent({ isColgroup: false, isMerge: false, isAllExpand: false, + useStyle: false, original: false, message: true, isHeader: false, @@ -417,10 +418,11 @@ export default defineComponent({ }) const computeIsMenu = computed(() => { + const menuOpts = computeMenuOpts.value const headerMenu = computeHeaderMenu.value const bodyMenu = computeBodyMenu.value const footerMenu = computeFooterMenu.value - return headerMenu.length || bodyMenu.length || footerMenu.length + return !!(props.menuConfig && isEnableConf(menuOpts) && (headerMenu.length || bodyMenu.length || footerMenu.length)) }) const computeMenuList = computed(() => { @@ -533,6 +535,7 @@ export default defineComponent({ computeKeyboardOpts, computeClipOpts, computeFNROpts, + computeIsMenu, computeMenuOpts, computeExportOpts, computeImportOpts, @@ -1125,6 +1128,7 @@ export default defineComponent({ const containerList = ['main', 'left', 'right'] const emptyPlaceholderElem = refEmptyPlaceholder.value const cellOffsetWidth = computeCellOffsetWidth.value + const mouseOpts = computeMouseOpts.value const bodyWrapperElem = elemStore['main-body-wrapper'] if (emptyPlaceholderElem) { emptyPlaceholderElem.style.top = `${headerHeight}px` @@ -1326,7 +1330,7 @@ export default defineComponent({ if (currentRow) { tableMethods.setCurrentRow(currentRow) } - if (mouseConfig && mouseConfig.selected && editStore.selected.row && editStore.selected.column) { + if (mouseConfig && mouseOpts.selected && editStore.selected.row && editStore.selected.column) { $xetable.addCellSelectedClass() } return nextTick() @@ -4934,11 +4938,26 @@ export default defineComponent({ if (props.treeConfig && checkboxOpts.range) { UtilTools.error('vxe.error.noTree', ['checkbox-config.range']) } - if (mouseOpts.area && !$xetable.handleUpdateCellAreas) { - return UtilTools.error('vxe.error.notProp', ['mouse-config.area']) - } - if (props.treeConfig && mouseOpts.area) { - UtilTools.error('vxe.error.noTree', ['mouse-config.area']) + + if (process.env.VUE_APP_VXE_TABLE_ENV === 'development') { + if (!$xetable.handleUpdateCellAreas) { + if (props.clipConfig) { + UtilTools.warn('vxe.error.notProp', ['clip-config']) + } + if (props.fnrConfig) { + UtilTools.warn('vxe.error.notProp', ['fnr-config']) + } + if (mouseOpts.area) { + UtilTools.error('vxe.error.notProp', ['mouse-config.area']) + return + } + } + if (mouseOpts.area && mouseOpts.selected) { + UtilTools.error('vxe.error.errConflicts', ['mouse-config.area', 'mouse-config.selected']) + } + if (props.treeConfig && mouseOpts.area) { + UtilTools.error('vxe.error.noTree', ['mouse-config.area']) + } } // 检查是否有安装需要的模块 diff --git a/packages/v-x-e-table/src/renderer.ts b/packages/v-x-e-table/src/renderer.ts index 034bc0c5f..adb94ff8a 100644 --- a/packages/v-x-e-table/src/renderer.ts +++ b/packages/v-x-e-table/src/renderer.ts @@ -164,7 +164,6 @@ function getEditOns (renderOpts: any, params: any) { const { $table, row, column } = params const { model } = column return getComponentOns(renderOpts, params, (cellValue: any) => { - console.log(cellValue) // 处理 model 值双向绑定 if (lazyInputComponents.indexOf(renderOpts.name) === -1 || isSyncCell(renderOpts, params)) { UtilTools.setCellValue(row, column, cellValue) diff --git a/types/export.d.ts b/types/export.d.ts index d8f950685..424d6a93f 100644 --- a/types/export.d.ts +++ b/types/export.d.ts @@ -65,6 +65,16 @@ declare module './grid' { declare module './table' { interface VxeTableMethods extends TableExportMethods { } interface VxeTablePrivateMethods extends TableExportPrivateMethods { } + namespace VxeTableDefines { + interface ExtortSheetMethodParams { + $table: VxeTableConstructor; + $grid?: VxeGridConstructor; + options: VxeTablePropTypes.ExportHandleOptions; + datas: any[]; + columns: VxeTableDefines.ColumnInfo[]; + colgroups: VxeTableDefines.ColumnInfo[][]; + } + } namespace VxeTablePropTypes { /** * 导入参数 @@ -112,7 +122,7 @@ declare module './table' { export interface ImportHandleOptions extends ImportConfig { data: any[]; columns: VxeTableDefines.ColumnInfo[]; - colgroups: VxeTableDefines.ColumnInfo[]; + colgroups: VxeTableDefines.ColumnInfo[][]; } interface ExportOrPrintColumnOption { @@ -195,26 +205,31 @@ declare module './table' { * 是否服务端导出 */ remote?: boolean; + /** + * 只对 remote=html,xlsx 有效,是否使用样式 + */ + useStyle?: boolean; + sheetMethod?(params: VxeTableDefines.ExtortSheetMethodParams): void; /** * 只对 remote=true 有效,用于自定义导出逻辑 */ exportMethod?(params: { $table: VxeTableConstructor; $grid?: VxeGridConstructor; - options: VxeTablePropTypes.ExportHandleOptions; + options: ExportHandleOptions; }): Promise; beforeExportMethod?(params: { - options: VxeTablePropTypes.ExportHandleOptions; + options: ExportHandleOptions; }): void; afterExportMethod?(params: { - options: VxeTablePropTypes.ExportHandleOptions; + options: ExportHandleOptions; }): void; } export interface ExportOpts extends ExportConfig { } export interface ExportHandleOptions extends ExportConfig { data: any[]; columns: VxeTableDefines.ColumnInfo[]; - colgroups: VxeTableDefines.ColumnInfo[]; + colgroups: VxeTableDefines.ColumnInfo[][]; } /** diff --git a/types/table.d.ts b/types/table.d.ts index 62509d987..f2e70ff18 100644 --- a/types/table.d.ts +++ b/types/table.d.ts @@ -62,6 +62,7 @@ export interface TablePrivateComputed { computeKeyboardOpts: ComputedRef; computeClipOpts: ComputedRef; computeFNROpts: ComputedRef; + computeIsMenu: ComputedRef; computeMenuOpts: ComputedRef; computeExportOpts: ComputedRef; computeImportOpts: ComputedRef; @@ -854,6 +855,7 @@ export interface TableReactData { type: any; isColgroup: boolean; isMerge: boolean; + useStyle: boolean; original: boolean; message: boolean; isHeader: boolean; diff --git a/types/v-x-e-table/interceptor.d.ts b/types/v-x-e-table/interceptor.d.ts index fa4625504..3a87d5405 100644 --- a/types/v-x-e-table/interceptor.d.ts +++ b/types/v-x-e-table/interceptor.d.ts @@ -13,7 +13,7 @@ export namespace VxeGlobalInterceptorHandles { export interface InterceptorKeydownParams extends InterceptorParams { } export interface InterceptorExportParams extends InterceptorParams { - options: VxeTablePropTypes.ExportConfig; + options: VxeTablePropTypes.ExportHandleOptions; columns: VxeTableDefines.ColumnInfo[]; colgroups: VxeTableDefines.ColumnInfo[][]; datas: any[]; @@ -21,7 +21,7 @@ export namespace VxeGlobalInterceptorHandles { export interface InterceptorImportParams extends InterceptorParams { file: File; - options: VxeTablePropTypes.ExportConfig; + options: VxeTablePropTypes.ExportHandleOptions; columns: VxeTableDefines.ColumnInfo[]; datas: any[]; }