yw-common-list
Version:
基于vxe-table封装的自定义可配置表格
587 lines (583 loc) • 19.5 kB
JavaScript
/**
* lz,2022-09-13 10:13
* 调用接口的通用列表
*/
import { Button } from '../../button'
// import { VXETable } from '../../v-x-e-table'
// 引入通用表格
import aCommonList from '../../a-common-list/src/list'
// 引入高级查询
import advancedQuery from '../../advanced-query/src/query'
// 引入分页
import VxePager from '../../pager/src/pager'
// 引入配置信息
import options from './options'
// 引入axios用于请求接口
import { axios } from './request'
// 监听尺寸变化
// import resize from './resize'
export default {
name: 'ya-wei-list',
inheritAttrs: false,
// mixins: [resize],
data () {
return {
// 表格数据
tableData: [],
// 表格列
columns: [],
// 表格加载状态
loading: false,
// 表格配置
tableOption: {},
// 表格分页数据
tablePage: {
// 当前页
pageNo: 1,
// 每页数据量
pageSize: options.pageSize,
// 列表总量
totalResult: 0
},
// 排序所需数据
tableSort: {},
// 是否显示高级查询
showQuery: false,
// 高级查询页面渲染所需数据
queryOption: [],
// 列表高级查询查询条件
listQuery: {},
// 错误信息
errorMessage: null,
// 记录最后一次的查询方式,手动触发 reload / 高级查询 superQuery
searchType: null,
// 监听传值 query 是否变更
updatePropQuery: false
}
},
props: {
// 表格配置key
tableKey: {
type: String,
require: true
},
// 是否显示分页
showTablePage: {
type: Boolean,
default: true
},
// 是否显示表格上方区域
showTop: {
type: Boolean,
default: true
},
// 是否显示高级查询
showAdvancedQuery: {
type: Boolean,
default: true
},
// 高级查询页面弹窗用的数据回显
advancedPopupData: {
type: Object,
default: () => ({})
},
// 自定义分页参数
customPage: {
type: Object,
default: () => {
return {
// 当前页
pageNo: options.pageNo,
// 每页数据量
pageSize: options.pageSize,
// 列表总量
totalResult: 0
}
}
},
// 列表高级查询查询条件
superParams: {
type: Array,
default: () => []
},
// 查询条件,会被高级查询覆盖
query: {
type: Object,
default: () => {
return {}
}
},
// 高级查询选中与 query 独立
superQueryAlone: {
type: Boolean,
default: true
},
// 高级查询选中与 query 独立的参数名
superQueryAloneParams: {
type: Array,
default: () => ['id', 'column', 'order']
},
// 初始化默认加载数据
defaultReload: {
type: Boolean,
default: false
},
// 高级查询是否支持回车提交
superQueryEnterSubmit: {
type: Boolean,
default: true
}
},
// 监听属性 类似于data概念",
computed: {},
// 监控data中的数据变化",
watch: {
// 监听表格key
tableKey () {
this.initTable()
},
query: {
deep: true,
handler (val, old) {
this.updatePropQuery = JSON.stringify(this.removeEmptyData(val)) !== JSON.stringify(this.removeEmptyData(old))
}
},
advancedPopupData: {
deep: true,
handler (val) {
if (this.showAdvancedQuery) {
this.$refs.refAdvancedQuery.updateData(val)
}
}
}
/* ,
// 深度监听自定义分页
customPage: {
deep: true, // 深度监听
immediate: true, // 立即触发
handler (val) {
if (val) this.initTablePage()
}
} */
},
methods: {
// 获取表格当前选中数据
getCheckboxRecords () {
const ref = this.tableKey
return this.$refs[ref]?.$refs[ref]?.getCheckboxRecords() || []
},
// 分页触发方法
handlePageChange ({ currentPage, pageSize }) {
this.tablePage.pageNo = currentPage
this.tablePage.pageSize = pageSize
this.initData()
},
// 清空数据
clearData () {
this.tableData = []
this.columns = []
this.loading = false
this.tableOption = {}
this.tablePage = {
pageNo: options.pageNo,
pageSize: options.pageSize,
totalResult: 0
}
},
/**
* 刷新表格
* @param e 所需查询参数
* @param back 是否为返回,返回不对searchType进行修改
* @returns {Promise<unknown>} 接口返回数据
*/
reload (e, back = false) {
if (back) {
this.tableData = []
this.loading = false
return this.initData()
}
let searchType = 'reload'
if (e && Object.keys(e).length > 0) {
if (this.isNotEmptyNumber(e.pageNo) && this.isNotEmptyNumber(e.pageSize)) {
if (this.searchType === 'superQuery' && !this.updatePropQuery) {
if (this.tablePage.pageNo !== e.pageNo || this.tablePage.pageSize !== e.pageSize) {
searchType = 'superQuery'
}
}
this.tablePage = { ...e }
}
}
this.searchType = searchType
this.tableData = []
this.loading = false
return this.initData()
},
// 清空对象中空数据
removeEmptyData: function (data) {
const keys = Object.keys(data)
if (!data || (data && keys.length < 0)) return {}
const filter = {}
keys.forEach(key => {
const value = data[key]
if (value !== null && value !== '' && typeof value !== 'undefined') {
filter[key] = value
}
})
return filter
},
// 判断不为空数字
isNotEmptyNumber (str) {
return str !== '' && str !== null && typeof str !== 'undefined'
},
// 初始化表格
initTable (str) {
this.clearData()
this.initOption()
.then(() => {
if (str === 'created' && this.defaultReload) {
this.initData()
}
})
},
// 初始化分页
initTablePage (e) {
// 自定义分页数据不存在或者开启分页,不使用自定义分页数据
if (this.showTablePage) {
this.tablePage = {
pageNo: e.pageNo || options.pageNo,
pageSize: e.pageSize || options.pageSize,
totalResult: e?.total
}
} else if (this.customPage) {
const page = { ...this.customPage }
if (Object.keys(page).length > 0) {
this.tablePage = page
}
}
},
// 初始化表格数据
async initData () {
try {
this.loading = true
const { success, result } = await this.getTableData()
if (success) {
this.tableData = result.records || []
this.tablePage.totalResult = result.total || 0
result.pageNo = this.tablePage.pageNo
result.superQuery = this.listQuery
result.isSuperQuery = this.searchType === 'superQuery'
this.$emit('listLoaderSuccess', result)
return new Promise(resolve => resolve(result))
}
} catch (e) {
this.errorMessage = `${e.code}-${e.message}`
} finally {
this.loading = false
}
},
// 设置表格尺寸
initTableSize () {
// console.log('tableSize')
// const { clientWidth, clientHeight } = this.$el
// const option = { ...this.tableOption }
// if (clientWidth && clientHeight && !option.width && !option.height) {
// let height = clientHeight
// const buttonHeight = this.$refs.yaWeiListVXEToolbar?.$el.clientHeight
// const pageHeight = this.$refs.yaWeiListVXEPager?.$el.clientHeight
// // 如果显示上方按钮区域
// if (this.showTop) height -= buttonHeight || 51
// if (this.showTablePage) height -= pageHeight || 48
// option.width = clientWidth
// option.divHeight = height
// // option.height = height - (this.showTop ? buttonHeight || 51 : 0) - (this.showTablePage ? pageHeight || 48 : 0)
// option.height = 'auto'
// this.tableOption = option
// }
},
// 格式化表格所需参数
formatTableOption (result) {
const option = {
align: result.columnTitleAlign,
border: true, // 边框
stripe: true, // 斑马条纹
width: result.width, // 宽度
tableHeight: result.height || 'auto', // 高度
rowHeight: result.rowHeight // 行高
}
const { clientWidth, clientHeight } = this.$el
if (clientWidth && clientHeight && !result.width && !result.height) {
let height = clientHeight
const buttonHeight = this.$refs.yaWeiListVXEToolbar?.$el.clientHeight
const pageHeight = this.$refs.yaWeiListVXEPager?.$el.clientHeight
// 如果显示上方按钮区域
if (this.showTop) height -= buttonHeight || 51
if (this.showTablePage) height -= pageHeight || 48
option.width = clientWidth
option.divHeight = height
// option.height = height - (this.showTop ? buttonHeight || 51 : 0) - (this.showTablePage ? pageHeight || 48 : 0)
option.tableHeight = 'auto'
}
return option
},
// 格式化高级查询所需参数
formatQueryOption (e) {
const option = JSON.parse(JSON.stringify(e))
option.sort((a, b) => (a.superSort || 0) - (b.superSort || 0))
return option
},
// 初始化表格配置
async initOption () {
try {
const { success, result, message, code } = await this.getTableOption()
if (success) {
const relFields = result.relFields || []
this.queryOption = this.formatQueryOption(relFields)
this.tableOption = this.formatTableOption(result)
/* this.tableOption = {
align: result.columnTitleAlign,
border: true, // 边框
stripe: true, // 斑马条纹
width: result.width, // 宽度
height: result.height || 'auto', // 高度
rowHeight: result.rowHeight // 行高
}
this.initTableSize() */
this.initTablePage(result)
// 让columns最后赋值,避免出现意外情况
const timeout = setTimeout(() => {
this.initColumn(relFields)
clearTimeout(timeout)
}, 50)
} else {
this.errorMessage = `${code}-${message}`
}
} catch (e) {
this.errorMessage = `${e.code}-${e.message}`
} finally {
this.loading = false
}
},
// 初始化表格列
initColumn (list) {
let columns = []
const list1 = [...list]
// list1.filter(item => item.field).map(item => {
list1.map(item => {
const column = Object.assign(item, {
width: item.columnWidths,
title: item.fieldCn,
data: item.field,
field: item.fieldCode || item.field?.fieldName
})
if (item.columnSort) column.sort = item.columnSort
columns.push(column)
})
// columns = columns.filter(item => item.title)
columns = columns.filter(item => item.title && item.field)
/* columns.push({
columnAttributes: '-3',
width: 100,
title: '测试checkBox',
field: 'checkBox'
})
columns.push({
columnAttributes: '-2',
width: 100,
title: '操作',
field: 'caoZuo'
}) */
this.columns = columns || []
},
// 获取插槽所用数据
getScopedSlots (columns, h) {
const slots = {}
const $scopedSlots = this.$scopedSlots
if (columns && columns.length > 0) {
// 为所有列增加头部插槽,插槽名=列字段+Header
columns.map(item => {
const header = `${item.field}Header`
if ($scopedSlots[header]) {
slots[header] = (props) => {
return h('div', $scopedSlots[header](props))
}
}
// 判断当前列是否为自定义列,如果是增加与列字段同名的插槽
if (item.columnAttributes === -2 || item.columnAttributes === '-2') {
if ($scopedSlots[item.field]) {
slots[item.field] = (props) => {
return h('div', $scopedSlots[item.field](props))
}
}
}
})
}
return slots
},
// 通过接口调用获取表格配置
async getTableOption () {
const configName = this.tableKey
if (configName) {
let res = {}
if (this.$YaWeiListUseOption?.axios) {
this.$YaWeiListUseOption.axios.defaults.baseURL = options.baseUrl
res = await this.$YaWeiListUseOption.axios.get('grid-config/queryAllByName', { params: { configName } })
} else {
axios.defaults.baseURL = options.baseUrl
res = await axios.get('grid-config/queryAllByName', { params: { configName } })
}
// if (!res.success) VXETable.modal.message({ status: 'error', content: res.message || '查询表格配置失败' })
return Promise.resolve(res.data.data || res.data)
}
},
// 通过接口调用获取表格数据
async getTableData () {
// console.log(this.searchType, this.query, this.listQuery)
const configName = this.tableKey
if (configName) {
const { pageNo, pageSize } = this.tablePage
const superParams = this.superParams
const tableSort = this.tableSort
let listQuery = {}
if (this.superQueryAlone) {
if (this.searchType === 'reload') listQuery = { ...this.query, ...tableSort }
else if (this.searchType === 'superQuery') {
listQuery = { ...this.listQuery, ...tableSort }
if (this.query && Object.keys(this.query).length > 0 && this.superQueryAloneParams && this.superQueryAloneParams.length > 0) {
Object.keys(this.query).map(item => {
if (!this.superQueryAloneParams.includes(item)) listQuery[item] = this.query[item]
})
}
}
} else {
listQuery = { ...this.query, ...this.listQuery, ...tableSort }
}
let res = {}
if (this.$YaWeiListUseOption?.axios) {
this.$YaWeiListUseOption.axios.defaults.baseURL = options.baseUrl
res = await this.$YaWeiListUseOption.axios.post('list-common/queryCommonList', { superParams, listQuery },
{
params: {
configName,
pageNo,
pageSize
}
})
} else {
axios.defaults.baseURL = options.baseUrl
res = await axios.post('list-common/queryCommonList', { superParams, listQuery },
{
params: {
configName,
pageNo,
pageSize
}
})
}
// if (!res.success) VXETable.modal.message({ status: 'error', content: res.message || '查询表格数据失败' })
return Promise.resolve(res.data.data || res.data)
}
},
// 排序变更出发方法
sortChange (e) {
if (!e || Object.keys(e).length === 0 || !e.field) return
this.tableSort = e.order ? { column: e.field, order: e.order } : {}
this.$nextTick(() => {
this.initData()
})
}
},
// 生命周期 - 创建完成(可以访问当前this实例)",数据模型已加载,方法已加载,html模板已加载,html模板未渲染
created () {
this.initTable('created')
},
render (h) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
const that = this
const { tableOption, loading, tableData, columns, tablePage } = this.$data
const ref = this.tableKey
const aCommonListAttr = {
...this.$attrs,
tableKey: ref,
tableOption,
loading,
tableData,
columns
}
const scopedSlots = this.getScopedSlots(columns, h)
const vxePagerAttr = {
border: true,
loading,
currentPage: tablePage.pageNo,
pageSize: tablePage.pageSize,
total: tablePage.totalResult,
pageSizes: options.pageSizes,
layouts: ['PrevPage', 'JumpNumber', 'NextPage', 'FullJump', 'Sizes', 'Total']
}
// 是否显示分页
const showTablePage = this.showTablePage
// 是否显示高级查询
const showAdvancedQuery = this.showAdvancedQuery
const style = {}
if (tableOption.divHeight) style.height = `${tableOption.divHeight}px`
return h('div', { class: 'ya-wei-list', style },
this.errorMessage || [
this.showTop && h('vxe-toolbar', {
ref: 'yaWeiListVXEToolbar',
scopedSlots: {
buttons () {
return [that.$slots.buttons, h(Button, {
attrs: { content: '刷新', status: 'primary' },
on: {
click: () => {
that.initData()
}
}
}), showAdvancedQuery && h(Button, {
attrs: { content: '高级查询', status: 'primary' },
on: {
click: () => {
that.showQuery = true
}
}
})]
}
}
}),
showAdvancedQuery && h(advancedQuery, {
ref: 'refAdvancedQuery',
attrs: {
visible: this.showQuery,
option: this.queryOption || [],
tableKey: this.tableKey,
data: { ...(this.listQuery || {}), ...(this.advancedPopupData || {}) },
enterSubmit: this.superQueryEnterSubmit
},
on: {
updateVisible: (flag) => {
this.showQuery = flag
this.$emit('superQueryVisible', flag)
},
submit: (e) => {
this.listQuery = e
this.tablePage.pageNo = 1
this.searchType = 'superQuery'
this.initData()
this.$emit('superQuerySubmit', e)
},
focusCustom: (str) => {
this.$emit('focusCustom', str)
},
clearCustom: (str) => {
this.$emit('clearCustom', str)
},
resetForm: () => {
this.$emit('superQueryReset')
}
}
}),
h(aCommonList, { ref, attrs: aCommonListAttr, scopedSlots, on: { 'sort-change': this.sortChange, ...this.$listeners } }),
showTablePage && h(VxePager, { ref: 'yaWeiListVXEPager', attrs: vxePagerAttr, on: { 'page-change': this.handlePageChange } })
]
)
}
}