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

199 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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="() => (canSelect ? 'custom-table-row' : '')"
@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,
},
canDeselect: {
type: Boolean,
default: true,
},
// 多选
multiple: {
type: Boolean,
default: false,
},
// 鼠标移动选择
mouseMoveSelect: {
type: Boolean,
default: true,
},
},
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: {
// 实现单击选中/反选功能
customRow(record, index) {
const key = record[this.rowKey]
return {
class: this.innerSelectedRowKeys.includes(key) ? 'ant-table-row-selected' : '',
on: {
click: () => {
if (!this.canSelect) {
return
}
// 反选
if (this.innerSelectedRowKeys.includes(key)) {
if (this.multiple || this.canDeselect) {
const findIndex = this.innerSelectedRowKeys.findIndex((k) => k == key)
this.innerSelectedRowKeys.splice(findIndex, 1)
}
}
// 选中
else {
if (this.multiple) {
this.innerSelectedRowKeys.push(key)
} else {
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;
}
}
.mouse-move-select {
user-select: none;
::v-deep {
td {
transition: none !important;
}
}
}
</style>