From 68ca43fb12f986095cea1c6d5a7d641af7f80775 Mon Sep 17 00:00:00 2001 From: zer0Black Date: Thu, 15 Apr 2021 09:35:49 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E4=BF=AE=E6=94=B9=E3=80=91=E6=81=A2?= =?UTF-8?q?=E5=A4=8DSTable=E8=A1=A8=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jero-web/src/components/table/README.md | 292 ++++++++++++++++++ .../src/components/table/StandardTable.vue | 252 +++++++++++++++ jero-web/src/components/table/index.js | 269 ++++++++++++++++ .../src/views/demo/list/PermissionList.vue | 8 +- jero-web/src/views/demo/list/RoleList.vue | 8 +- .../views/demo/list/TableInnerEditList.vue | 8 +- jero-web/src/views/demo/list/TableList.vue | 8 +- jero-web/src/views/demo/list/UserList.vue | 8 +- 8 files changed, 833 insertions(+), 20 deletions(-) create mode 100644 jero-web/src/components/table/README.md create mode 100644 jero-web/src/components/table/StandardTable.vue create mode 100644 jero-web/src/components/table/index.js diff --git a/jero-web/src/components/table/README.md b/jero-web/src/components/table/README.md new file mode 100644 index 00000000..ad5f6413 --- /dev/null +++ b/jero-web/src/components/table/README.md @@ -0,0 +1,292 @@ +Table 重封装组件说明 +==== + + +封装说明 +---- + +> 基础的使用方式与 API 与 [官方版(Table)](https://vuecomponent.github.io/ant-design-vue/components/table-cn/) 本一致,在其基础上,封装了加载数据的方法。 +> +> 你无需在你是用表格的页面进行分页逻辑处理,仅需向 Table 组件传递绑定 `:data="Promise"` 对象即可 + + + +例子1 +---- +(基础使用) + +```vue + + + + + +``` + + + +例子2 +---- + +(简单的表格,最后一列是各种操作) + +```vue + + + +``` + + + +内置方法 +---- + +通过 `this.$refs.table` 调用 + +`this.$refs.table.refresh()` 刷新列表 (用户新增/修改数据后,重载列表数据) + +> 注意:要调用 `refresh()` 需要给表格组件设定 `ref` 值 + + + +注意事项 +---- + +> 你可能需要为了与后端提供的接口返回结果一致而去修改以下代码: +(需要注意的是,这里的修改是全局性的,意味着整个项目所有使用该 table 组件都需要遵守这个返回结果定义的字段。) + +修改 `@/components/table/index.js` 第 106 行起 + + + +```javascript +result.then(r => { + this.localPagination = Object.assign({}, this.localPagination, { + current: r.pageNo, // 返回结果中的当前分页数 + total: r.totalCount, // 返回结果中的总记录数 + showSizeChanger: this.showSizeChanger, + pageSize: (pagination && pagination.pageSize) || + this.localPagination.pageSize + }); + + !r.totalCount && ['auto', false].includes(this.showPagination) && (this.localPagination = false) + this.localDataSource = r.data; // 返回结果中的数组数据 + this.localLoading = false +}); +``` +返回 JSON 例子: +```json +{ + "message": "", + "result": { + "data": [{ + id: 1, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/WdGqmHpayyMjiEhcKoVE.png', + title: 'Alipay', + description: '那是一种内在的东西, 他们到达不了,也无法触及的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 2, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png', + title: 'Angular', + description: '希望是一个好东西,也许是最好的,好东西是不会消亡的', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 3, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/dURIMkkrRFpPgTuzkwnB.png', + title: 'Ant Design', + description: '城镇中有那么多的酒馆,她却偏偏走进了我的酒馆', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 4, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png', + title: 'Ant Design Pro', + description: '那时候我只会想自己想要什么,从不想自己拥有什么', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 5, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/siCrBXXhmvTQGWPNLBow.png', + title: 'Bootstrap', + description: '凛冬将至', + status: 1, + updatedAt: '2018-07-26 00:00:00' + }, + { + id: 6, + cover: 'https://gw.alipayobjects.com/zos/rmsportal/ComBAopevLwENQdKWiIn.png', + title: 'Vue', + description: '生命就像一盒巧克力,结果往往出人意料', + status: 1, + updatedAt: '2018-07-26 00:00:00' + } + ], + "pageSize": 10, + "pageNo": 0, + "totalPage": 6, + "totalCount": 57 + }, + "status": 200, + "timestamp": 1534955098193 +} +``` + + + +更新时间 +---- + +该文档最后更新于: 2018-10-31 PM 08:15 \ No newline at end of file diff --git a/jero-web/src/components/table/StandardTable.vue b/jero-web/src/components/table/StandardTable.vue new file mode 100644 index 00000000..bc6044ac --- /dev/null +++ b/jero-web/src/components/table/StandardTable.vue @@ -0,0 +1,252 @@ + + + + + \ No newline at end of file diff --git a/jero-web/src/components/table/index.js b/jero-web/src/components/table/index.js new file mode 100644 index 00000000..ffb65110 --- /dev/null +++ b/jero-web/src/components/table/index.js @@ -0,0 +1,269 @@ +import T from "ant-design-vue/es/table/Table"; +import get from "lodash.get" +export default { + data() { + return { + needTotalList: [], + + selectedRows: [], + selectedRowKeys: [], + + localLoading: false, + localDataSource: [], + localPagination: Object.assign({}, T.props.pagination) + }; + }, + props: Object.assign({}, T.props, { + rowKey: { + type: [String, Function], + default: 'id' + }, + data: { + type: Function, + required: true + }, + pageNum: { + type: Number, + default: 1 + }, + pageSize: { + type: Number, + default: 10 + }, + showSizeChanger: { + type: Boolean, + default: true + }, + showAlertInfo: { + type: Boolean, + default: false + }, + showPagination: { + default: 'auto' + } + }), + watch: { + 'localPagination.current'(val) { + this.$router.push({ + name: this.$route.name, + params: Object.assign({}, this.$route.params, { + pageNo: val + }), + }); + }, + pageNum(val) { + Object.assign(this.localPagination, { + current: val + }); + }, + pageSize(val) { + console.log('pageSize:', val) + Object.assign(this.localPagination, { + pageSize: val + }); + }, + showSizeChanger(val) { + console.log('showSizeChanger', val) + Object.assign(this.localPagination, { + showSizeChanger: val + }); + } + }, + created() { + this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, { + current: this.pageNum, + pageSize: this.pageSize, + showSizeChanger: this.showSizeChanger + }); + this.needTotalList = this.initTotalList(this.columns) + this.loadData(); + }, + methods: { + refresh() { + this.loadData(); + }, + loadData(pagination, filters, sorter) { + + this.localLoading = true + var result = this.data( + Object.assign({ + pageNo: (pagination && pagination.current) || + this.localPagination.current, + pageSize: (pagination && pagination.pageSize) || + this.localPagination.pageSize + }, + (sorter && sorter.field && { + sortField: sorter.field + }) || {}, + (sorter && sorter.order && { + sortOrder: sorter.order + }) || {}, { + ...filters + } + ) + ); + + if (result instanceof Promise) { + result.then(r => { + this.localPagination = Object.assign({}, this.localPagination, { + current: r.pageNo, // 返回结果中的当前分页数 + total: r.totalCount, // 返回结果中的总记录数 + showSizeChanger: this.showSizeChanger, + pageSize: (pagination && pagination.pageSize) || + this.localPagination.pageSize + }); + //update--begin--autor:wangshuai-----date:20200724------for:判断showPagination是否为false------ + (!this.showPagination || !r.totalCount && this.showPagination === 'auto') && (this.localPagination = false) + //update--end--autor:wangshuai-----date:20200724------for:判断showPagination是否为false----- + this.localDataSource = r.data; // 返回结果中的数组数据 + this.localLoading = false + }); + } + }, + initTotalList(columns) { + const totalList = [] + columns && columns instanceof Array && columns.forEach(column => { + if (column.needTotal) { + totalList.push({ ...column, + total: 0 + }) + } + }) + return totalList + }, + updateSelect(selectedRowKeys, selectedRows) { + this.selectedRowKeys = selectedRowKeys + this.selectedRows = selectedRows + let list = this.needTotalList + this.needTotalList = list.map(item => { + return { + ...item, + total: selectedRows.reduce((sum, val) => { + let total = sum + get(val, item.dataIndex) + return isNaN(total) ? 0 : total + }, 0) + } + }) + // this.$emit('change', selectedRowKeys, selectedRows) + }, + updateEdit() { + this.selectedRows = [] + }, + onClearSelected() { + // 【TESTA-262】页面清空后还能才做所选行,增加 this.$emit('clearAll') + this.selectedRowKeys = [] + this.selectedRows = [] + this.updateSelect([], []) + this.$emit('clearAll') + }, + renderMsg(h) { + const _vm = this + let d = [] + // 构建 已选择 + d.push( + h('span', { + style: { + marginRight: '12px' + } + }, ['已选择 ', h('a', { + style: { + fontWeight: 600 + } + }, this.selectedRows.length)]) + ); + + // 构建 列统计 + this.needTotalList.map(item => { + d.push(h('span', { + style: { + marginRight: '12px' + } + }, + [ + `${ item.title }总计 `, + h('a', { + style: { + fontWeight: 600 + } + }, `${ !item.customRender ? item.total : item.customRender(item.total) }`) + ])) + }); + + // 构建 清空选择 + d.push(h('a', { + style: { + marginLeft: '24px' + }, + on: { + click: _vm.onClearSelected + } + }, '清空')) + + return d + }, + renderAlert(h) { + return h('span', { + slot: 'message' + }, this.renderMsg(h)) + }, + }, + + render(h) { + const _vm = this + + let props = {}, + localKeys = Object.keys(this.$data); + + Object.keys(T.props).forEach(k => { + let localKey = `local${k.substring(0,1).toUpperCase()}${k.substring(1)}`; + if (localKeys.includes(localKey)) { + return props[k] = _vm[localKey]; + } + return props[k] = _vm[k]; + }) + + + // 显示信息提示 + if (this.showAlertInfo) { + + props.rowSelection = { + selectedRowKeys: this.selectedRowKeys, + onChange: (selectedRowKeys, selectedRows) => { + _vm.updateSelect(selectedRowKeys, selectedRows) + _vm.$emit('onSelect', { selectedRowKeys: selectedRowKeys, selectedRows: selectedRows }) + } + }; + + return h('div', {}, [ + h("a-alert", { + style: { + marginBottom: '16px' + }, + props: { + type: 'info', + showIcon: true + } + }, [_vm.renderAlert(h)]), + h("a-table", { + tag: "component", + attrs: props, + on: { + change: _vm.loadData + }, + scopedSlots: this.$scopedSlots + }, this.$slots.default) + ]); + + } + + return h("a-table", { + tag: "component", + attrs: props, + on: { + change: _vm.loadData + }, + scopedSlots: this.$scopedSlots + }, this.$slots.default); + + } +}; \ No newline at end of file diff --git a/jero-web/src/views/demo/list/PermissionList.vue b/jero-web/src/views/demo/list/PermissionList.vue index 2bf9f4f8..fe2aaffc 100644 --- a/jero-web/src/views/demo/list/PermissionList.vue +++ b/jero-web/src/views/demo/list/PermissionList.vue @@ -27,7 +27,7 @@ - + {{ action.describe }} @@ -57,7 +57,7 @@ - +