<template>
<div>
<table class="table">
<thead>
<tr>
<th>
<input type="checkbox" :indeterminate="isIndeterminate" v-model="allSelected" style="width:102px" />
</th>
<th v-for="(column, index) in columns" :key="column.key" :style="{ width: column.width + 'px' }">
<div class="header">
{{ column.title }}
<span class="resizer" @mousedown="startResize($event, index)" />
</div>
</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in data" :key="item.id">
<td style="width:102px">
<input type="checkbox" v-model="selectedRows" :value="item.id" />
</td>
<td v-for="column in columns" :key="column.key">{{ item[column.key] }}</td>
</tr>
</tbody>
</table>
<div>
<button @click="handleDelete">删除选中项</button>
</div>
</div>
</template>
<script>
import { ref, reactive, computed } from 'vue'
export default {
name: 'MultiSelectTable',
props: {
data: {
type: Array,
required: true,
},
columns: {
type: Array,
required: true,
},
},
setup(props, { emit }) {
const selectedRows = ref([]);
const allSelected = computed({
get: () => {
return selectedRows.value.length === props.data.length && props.data.length > 0;
},
set: (value) => {
selectedRows.value = value ? props.data.map(item => item.id) : [];
}
});
const isIndeterminate = computed(() => {
return selectedRows.value.length > 0 && selectedRows.value.length < props.data.length;
});
const handleDelete = () => {
emit("delete", selectedRows.value);
selectedRows.value = [];
};
// Drag resize column width
const startResize = (event, index) => {
const startX = event.clientX;
const startWidth = props.columns[index].width;
// const resize = (e) => {
// const newWidth = startWidth + (e.clientX - startX);
//if (newWidth > 50) { // Minimum width
props.columns[index].width = props.columns[index].width + 10;
//}
// };
// const stopResize = () => {
// document.removeEventListener('mousemove', resize);
// document.removeEventListener('mouseup', stopResize);
// };
// document.addEventListener('mousemove', resize);
// document.addEventListener('mouseup', stopResize);
};
return {
selectedRows,
allSelected,
isIndeterminate,
handleDelete,
startResize,
};
},
}
</script>
<style scoped>
.table {
width: 100%;
border-collapse: collapse;
}
.table th,
.table td {
border: 1px solid #ddd;
padding: 8px;
}
.table th {
background-color: #f2f2f2;
text-align: left;
position: relative;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
}
.resizer {
cursor: col-resize;
width: 5px;
height: 100%;
position: absolute;
top: 0;
right: 0;
z-index: 1;
}
</style>