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({}, this.pagination), isSucceed: true ,// 是否请求成功 leftAlignId:"", } }, props: Object.assign({}, T.props, { rowKey: { type: [String, Function], default: 'key' }, rowKeyName: { // 多选时,唯一标识键名 type: String, default: 'id' }, rowClassName: { type: [String, Function], default: '' }, data: { type: Function, required: true }, pageNum: { type: Number, default: 1 }, pageSize: { type: Number, default: 20 }, showSizeChanger: { type: Boolean, default: true }, size: { type: String, default: 'default' }, /** * alert: { * show: true, * clear: Function * } */ alert: { type: [Object, Boolean], default: null }, rowSelection: { type: Object, default: null }, showPagination: { type: String | Boolean, default: 'auto' }, /** * enable page URI mode * * e.g: * /users/1 * /users/2 * /users/3?queryParam=test * ... */ pageURI: { type: Boolean, default: false }, /** 是否首次加载数据 */ defaultLoadData: { type: Boolean, default: true }, tableId: { type: String, default: '' }, index: { type: [String, Number], default: '' } }), watch: { 'localPagination.current' (val) { this.pageURI && this.$router.push({ ...this.$route, name: this.$route.name, params: Object.assign({}, this.$route.params, { pageNo: val }) }) }, pageNum (val) { Object.assign(this.localPagination, { current: val }) }, pageSize (val) { Object.assign(this.localPagination, { pageSize: val }) }, showSizeChanger (val) { Object.assign(this.localPagination, { showSizeChanger: val }) } }, created () { const { pageNo } = this.$route.params const localPageNum = this.pageURI && (pageNo && parseInt(pageNo)) || this.pageNum this.localPagination = ['auto', true].includes(this.showPagination) && Object.assign({}, this.localPagination, { current: localPageNum, pageSize: this.pageSize, pageSizeOptions: ['5', '10', '20', '30', '40'], showTotal: total => `共 ${total} 条记录`, showSizeChanger: this.showSizeChanger }) || false this.needTotalList = this.initTotalList(this.columns) if (this.defaultLoadData) { this.loadData() } }, methods: { /** * 表格重新加载方法 * 如果参数为 true, 则强制刷新到第一页 * @param Boolean bool */ refresh (bool = false) { bool && (this.localPagination = Object.assign({}, { current: 1, pageSize: this.pageSize })) this.loadData() }, // 重置表格为空 clearTable () { this.localLoading = false this.localDataSource = [] this.needTotalList = [] this.clearSelected() this.localPagination = Object.assign({}, { current: 1, pageSize: this.pageSize, total: 0 }) }, /** * 加载数据方法 * @param {Object} pagination 分页选项器 * @param {Object} filters 过滤条件 * @param {Object} sorter 排序条件 */ loadData (pagination, filters, sorter) { this.localLoading = true const parameter = Object.assign({ pageNo: (pagination && pagination.current) || this.showPagination && this.localPagination.current || this.pageNum, pageSize: (pagination && pagination.pageSize) || this.showPagination && this.localPagination.pageSize || this.pageSize, tableId: this.tableId, index: this.index }, (sorter && sorter.field && { sortField: sorter.field }) || {}, (sorter && sorter.order && { sortOrder: sorter.order }) || {}, { ...filters } ) // console.log('parameter', parameter) const result = this.data(parameter) // 对接自己的通用数据接口需要修改下方代码中的 r.pageNo, r.count, r.data // eslint-disable-next-line if ((typeof result === 'object' || typeof result === 'function') && typeof result.then === 'function') { result.then(r => { // const list = r.list || r.data || r let list = [] if (r) { list = r.list || r.data || r } // console.log(r,'rrrrrrrrrr') this.isSucceed = !!r this.localPagination = this.showPagination && Object.assign({}, this.localPagination, { current: r.pageNo, // 返回结果中的当前分页数 total: Number(r.count), // 返回结果中的总记录数 showSizeChanger: this.showSizeChanger, pageSize: (pagination && pagination.pageSize) || this.localPagination.pageSize }) || false // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页 if (list.length === 0 && this.showPagination && this.localPagination.current > 1) { this.localPagination.current-- this.loadData() return } // 这里用于判断接口是否有返回 r.count 且 this.showPagination = true 且 pageNo 和 pageSize 存在 且 count 小于等于 pageNo * pageSize 的大小 // 当情况满足时,表示数据不满足分页大小,关闭 table 分页功能 try { if ((['auto', true].includes(this.showPagination) && r.count <= (r.pageNo * this.localPagination.pageSize))) { // this.localPagination.hideOnSinglePage = true } } catch (e) { this.localPagination = false } this.localDataSource = list // 返回结果中的数组数据 this.localLoading = false }).catch(err => { this.clearTable() }) } }, initTotalList (columns) { const totalList = [] columns && columns instanceof Array && columns.forEach(column => { if (column.needTotal) { totalList.push({ ...column, total: 0 }) } }) return totalList }, /** * 用于更新已选中的列表数据 total 统计 * @param selectedRowKeys * @param selectedRows */ updateSelect (selectedRowKeys, selectedRows) { const list = this.needTotalList this.needTotalList = list.map(item => { return { ...item, total: this.selectedRows.reduce((sum, val) => { const total = sum + parseInt(get(val, item.dataIndex)) return isNaN(total) ? 0 : total }, 0) } }) const obj = { selectedRowKeys: this.selectedRowKeys, selectedRows: this.selectedRows } this.$emit('rowSelection', obj) }, onSelectChange (record, selected, selectedRows, nativeEvent) { if (selected) { // 选择 this.selectedRows.push(record) } else { // 取消 const selectedRowsArr = [] this.selectedRows.map(item => { if (this.selectedRowKeys.indexOf(item[this.rowKeyName]) != -1) { selectedRowsArr.push(item) } }) this.selectedRows = selectedRowsArr } this.updateSelect() }, // 本页全选/取消全选 onSelectAllChange (selected, selectedRows, changeRows) { const _this = this if (selected) { // 选择 this.selectedRows = [...this.selectedRows, ...changeRows] } else { // 取消 const arrIds = [] changeRows.map((item, index) => { arrIds.push(item[this.rowKeyName]) }) const arrs = [] this.selectedRows.map((item, index) => { if (arrIds.indexOf(item[this.rowKeyName]) == -1) { arrs.push(item) } }) this.selectedRows = arrs } this.updateSelect() }, // 设置 table 已选中项 setTableSelected (selectedRowKeys, selectedRows) { this.selectedRows = selectedRows this.selectedRowKeys = selectedRowKeys this.updateSelect() }, /** * 清空 table 已选中项 */ clearSelected () { if (this.rowSelection) { this.selectedRows = [] this.selectedRowKeys = [] this.updateSelect() } }, /** * 处理交给 table 使用者去处理 clear 事件时,内部选中统计同时调用 * @param callback * @returns {*} */ renderClear (callback) { if (this.selectedRowKeys.length <= 0) return null return ( { callback() this.clearSelected() }}>清空 ) }, renderAlert () { // 绘制统计列数据 const needTotalItems = this.needTotalList.map((item) => { return ( {item.title}总计 {!item.customRender ? item.total : item.customRender(item.total)} ) }) // 绘制 清空 按钮 const clearItem = (typeof this.alert.clear === 'boolean' && this.alert.clear) ? ( this.renderClear(this.clearSelected) ) : (this.alert !== null && typeof this.alert.clear === 'function') ? ( this.renderClear(this.alert.clear) ) : null // 绘制 alert 组件 return ( ) }, expandFun (expanded, record) { this.$emit('expand', expanded, record) }, // 自定义行 customRows(record, index) { return { // 自定义属性,也就是官方文档中的props,可通过条件来控制样式 style: { // 设置行背景色 'background-color': record[this.rowKeyName] == this.leftAlignId ? '#ffedeb' : '' }, on: { // 鼠标单击行 click: event => { // 记录当前点击的行标识 this.leftAlignId = record[this.rowKeyName] }, dblclick: (event) => { event.stopPropagation() this.$emit('dblclick', record, index) } } } }, }, render () { const props = {} const localKeys = Object.keys(this.$data) const showAlert = (typeof this.alert === 'object' && this.alert !== null && this.alert.show) && typeof this.rowSelection.selectedRowKeys !== 'undefined' || this.alert Object.keys(T.props).forEach(k => { const localKey = `local${k.substring(0, 1).toUpperCase()}${k.substring(1)}` if (localKeys.includes(localKey)) { props[k] = this[localKey] return props[k] } if (k === 'rowSelection') { if (this.rowSelection) { // 如果需要使用alert,则重新绑定 rowSelection 事件 props[k] = { ...this.rowSelection, selectedRowKeys: this.selectedRowKeys, onChange: (selectedRowKeys, selectedRows) => { this.selectedRowKeys = selectedRowKeys }, onSelect: (record, selected, selectedRows, nativeEvent) => { this.onSelectChange(record, selected, selectedRows, nativeEvent) }, onSelectAll: (selected, selectedRows, changeRows) => { this.onSelectAllChange(selected, selectedRows, changeRows) } } return props[k] } else if (!this.rowSelection) { // 如果没打算开启 rowSelection 则清空默认的选择项 props[k] = null return props[k] } } this[k] && (props[k] = this[k]) return props[k] }) if (!this.isSucceed) { // 请求失败 props['locale'] = { emptyText: '暂时无法获取数据,请刷新页面重试' } } // isSucceed const table = ( { Object.keys(this.$slots).map(name => ()) } ) return (
{ showAlert ? this.renderAlert() : null } { table }
) } }