vue3+h5+css+table
<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>