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>

 

posted on 2024-12-04 21:06  longlinji  阅读(12)  评论(0编辑  收藏  举报