简介:本文详细阐述如何基于vue3-easy-data-table库封装适配移动端的表格组件,通过响应式布局、性能优化及自定义功能扩展,解决移动端表格显示与交互的痛点,提供可复用的技术方案。
在移动端场景中,传统表格组件常面临以下问题:
vue3-easy-data-table是一个基于Vue 3的高性能表格库,其核心优势包括:
responsiveColumns属性配置不同屏幕宽度下的列显示/隐藏。
<template><MobileDataTable :columns="responsiveColumns" /></template><script setup>import { ref, computed } from 'vue';const screenWidth = ref(window.innerWidth);const responsiveColumns = computed(() => {return screenWidth.value < 768 ? mobileColumns : desktopColumns;});</script>
// 示例:长按事件const handleLongPress = (row) => {navigator.clipboard.writeText(row.id);};
virtual-scroll属性,设置合理的item-height。
<MobileDataTable:items="largeData":virtual-scroll="true":item-height="50"/>
<!-- MobileDataTable.vue --><template><div class="mobile-table-container"><div class="table-header"><!-- 自定义表头 --></div><vue3-easy-data-table:headers="processedHeaders":items="filteredItems":virtual-scroll="true"@row-click="handleRowClick"/><div class="table-footer"><!-- 分页控件 --></div></div></template>
interface MobileDataTableProps {items: Array<Record<string, any>>;columns: Array<{field: string;label: string;visible?: boolean; // 移动端是否显示width?: string | number;}>;pageSize?: number;enableSearch?: boolean;}
<el-dialog v-model="columnDialogVisible"><el-checkbox-group v-model="selectedColumns"><el-checkbox v-for="col in columns" :key="col.field" :label="col.field">{{ col.label }}</el-checkbox></el-checkbox-group></el-dialog>
xlsx库生成Excel文件:
import { writeFile } from 'xlsx';const exportToExcel = () => {const ws = XLSX.utils.json_to_sheet(processedItems.value);const wb = XLSX.utils.book_new();XLSX.utils.book_append_sheet(wb, ws, 'Sheet1');writeFile(wb, 'data.xlsx');};
<template><MobileDataTable:items="orders":columns="mobileColumns"@row-click="navigateToDetail"/></template><script setup>const mobileColumns = [{ field: 'id', label: '订单号', width: '120px' },{ field: 'productName', label: '商品' },{ field: 'amount', label: '金额', format: (val) => `¥${val}` },{ field: 'status', label: '状态', format: statusMap },];const navigateToDetail = (row) => {router.push(`/orders/${row.id}`);};</script>
import 'core-js/stable';import 'regenerator-runtime/runtime';
try {// 渲染逻辑} catch (e) {console.error('Table render error:', e);showFallbackUI();}
通过封装vue3-easy-data-table,我们实现了:
未来可扩展方向:
附录:完整组件代码
<!-- MobileDataTable.vue 完整版 --><template><div class="mobile-table"><div v-if="enableSearch" class="search-box"><el-input v-model="searchQuery" placeholder="搜索..." /></div><vue3-easy-data-table:headers="visibleHeaders":items="filteredItems":virtual-scroll="true":rows-per-page="pageSize"@row-click="handleRowClick"/><el-paginationv-model:current-page="currentPage":total="totalItems":page-size="pageSize"/></div></template><script setup>import { ref, computed } from 'vue';const props = defineProps({items: Array,columns: Array,pageSize: { type: Number, default: 10 },enableSearch: { type: Boolean, default: true }});const searchQuery = ref('');const currentPage = ref(1);const visibleHeaders = computed(() =>props.columns.filter(col => col.visible !== false));const filteredItems = computed(() => {if (!searchQuery.value) return props.items;const query = searchQuery.value.toLowerCase();return props.items.filter(item =>Object.values(item).some(val =>String(val).toLowerCase().includes(query)));});const totalItems = computed(() => filteredItems.value.length);const handleRowClick = (row) => {console.log('Row clicked:', row);// 触发自定义事件或路由跳转};</script><style scoped>.mobile-table {width: 100%;overflow-x: hidden;}.search-box {margin: 10px;}</style>