AnalysisSystemForRadionucli.../src/components/CustomTable/index.vue

222 lines
5.7 KiB
Vue
Raw Normal View History

<template>
<a-table
ref="tableRef"
class="custom-table"
:class="['custom-table', canSelect && multiple && mouseMoveSelect ? 'mouse-move-select' : '']"
v-bind="$attrs"
:data-source="list"
:columns="columns"
:size="size"
:row-key="rowKey"
:loading="loading"
:pagination="pagination"
:customRow="multiple && mouseMoveSelect ? customMouseMoveSelectRow : customRow"
:rowClassName="(record, index) => innerRowClassName(record, index)"
@change="handleTableChange"
>
<!-- 处理 scopedSlots -->
<template v-for="slotName of scopedSlotsKeys" :slot="slotName" slot-scope="text, record, index">
<slot :name="slotName" :text="text" :record="record" :index="index"></slot>
</template>
</a-table>
</template>
<script>
export default {
props: {
list: {
type: Array,
default: () => []
},
columns: {
type: Array,
default: () => []
},
size: {
type: String,
default: 'middle'
},
rowKey: {
type: String,
default: 'id'
},
loading: {
type: Boolean
},
pagination: {
type: [Object, Boolean]
},
selectedRowKeys: {
type: Array
},
selectionRows: {
type: Array
},
canSelect: {
type: Boolean,
default: true
2023-07-05 16:00:43 +08:00
},
canDeselect: {
type: Boolean,
default: true
2023-07-05 16:00:43 +08:00
},
// 多选
2023-07-05 16:00:43 +08:00
multiple: {
type: Boolean,
default: false
},
// 鼠标移动选择
mouseMoveSelect: {
type: Boolean,
default: true
},
customRowClassName: {
type: Function
}
},
data() {
return {
innerSelectedRowKeys: [],
innerSelectedRows: []
}
},
mounted() {
if (this.canSelect && this.multiple && this.mouseMoveSelect) {
const tbody = this.$el.querySelector('.ant-table-tbody')
tbody.addEventListener('mouseleave', () => {
this.mouseMoveStartIndex = undefined
})
}
},
methods: {
innerRowClassName(record, index) {
let className = ''
if (this.customRowClassName) {
className = this.customRowClassName({ record, index })
}
return (this.canSelect ? 'custom-table-row' : '') + ' ' + className
},
// 实现单击选中/反选功能
customRow(record, index) {
2023-07-05 16:00:43 +08:00
const key = record[this.rowKey]
return {
2023-07-05 16:00:43 +08:00
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
on: {
click: () => {
if (!this.canSelect) {
return
}
// 反选
2023-07-05 16:00:43 +08:00
if (this.innerSelectedRowKeys.includes(key)) {
if (this.multiple || this.canDeselect) {
const findIndex = this.innerSelectedRowKeys.findIndex(k => k == key)
this.innerSelectedRowKeys.splice(findIndex, 1)
2023-07-05 16:00:43 +08:00
}
}
// 选中
else {
if (this.multiple) {
2023-07-05 16:00:43 +08:00
this.innerSelectedRowKeys.push(key)
} else {
2023-07-05 16:00:43 +08:00
this.innerSelectedRowKeys = [key]
}
}
this.$emit('detail', record)
this.$emit('rowClick', record, index)
},
dblclick: () => {
this.$emit('rowDblClick', record, index)
}
}
}
},
// 实现鼠标拖移动多选功能
customMouseMoveSelectRow(record, index) {
const key = record[this.rowKey]
return {
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
on: {
mousedown: () => {
this.innerSelectedRowKeys = []
this.mouseMoveStartIndex = index
},
mouseenter: () => {
if (this.mouseMoveStartIndex !== undefined) {
const indexes = [this.mouseMoveStartIndex, index].sort((a, b) => a - b)
this.innerSelectedRowKeys = this.list.slice(indexes[0], indexes[1] + 1).map(item => item[this.rowKey])
}
},
mouseup: () => {
// 开始和结束在同一个相当于click
if (this.mouseMoveStartIndex == index) {
this.innerSelectedRowKeys = [key]
}
this.mouseMoveStartIndex = undefined
}
}
}
},
handleTableChange(pagination, filters, sorter) {
this.$emit('change', pagination, filters, sorter)
},
// 让第index行滚动到视野范围
scrollIntoView(index) {
const tableEle = this.$refs.tableRef.$el
const tableBodyEle = tableEle.querySelector('.ant-table-body')
const prevEle = tableBodyEle.querySelector(`.ant-table-row:nth-child(${index + 1})`)
tableBodyEle.scrollTop = prevEle.offsetTop
}
},
watch: {
selectedRowKeys(val) {
this.innerSelectedRowKeys = val
},
innerSelectedRowKeys() {
this.$emit('update:selectedRowKeys', this.innerSelectedRowKeys)
this.innerSelectedRows = this.innerSelectedRowKeys.map(key => {
return this.list.find(item => item[this.rowKey] === key)
})
this.$emit('update:selectionRows', this.innerSelectedRows)
}
},
computed: {
scopedSlotsKeys() {
return Object.keys(this.$scopedSlots)
}
}
}
</script>
<style lang="less" scoped>
::v-deep {
.custom-table-row {
cursor: pointer;
}
2025-05-26 18:12:59 +08:00
.ant-table-bordered .ant-table-header > table,
.ant-table-bordered .ant-table-body > table,
.ant-table-bordered .ant-table-fixed-left table,
.ant-table-bordered .ant-table-fixed-right table {
border-color: #416f7f;
}
.ant-table-bordered .ant-table-thead > tr > th,
.ant-table-bordered .ant-table-tbody > tr > td {
2025-05-26 18:12:59 +08:00
border-color: #416f7f;
}
}
.mouse-move-select {
user-select: none;
::v-deep {
td {
transition: none !important;
}
}
2023-05-16 19:45:54 +08:00
}
</style>