插槽设计
- 默认插槽:用于放置表格主体内容,如行、列等基本结构。
<template>
<table>
<thead>
<tr>
<th v-for="(col, index) in columns" :key="index">{{col.label}}</th>
</tr>
</thead>
<tbody>
<slot></slot>
</tbody>
</table>
</template>
- 具名插槽:
- header插槽:用于自定义表头,比如添加搜索框、表头操作按钮等。
<template>
<table>
<thead>
<slot name="header"></slot>
</thead>
<tbody>
<slot></slot>
</tbody>
</table>
</template>
- footer插槽:用于自定义表尾,例如显示分页信息等。
<template>
<table>
<thead>
<slot name="header"></slot>
</thead>
<tbody>
<slot></slot>
</tbody>
<tfoot>
<slot name="footer"></slot>
</tfoot>
</table>
</template>
性能优化策略
- 虚拟列表:对于大数据量表格,采用虚拟列表技术,只渲染可见区域的行。以 Vue 为例,可以使用
vue - virtual - scroll - list
库。
<template>
<div>
<vue - virtual - scroll - list
:data="tableData"
:height="400"
:item - height="30"
key - field="id"
>
<template #default="{ item }">
<tr>
<td v - for="(col, index) in columns" :key="index">{{item[col.field]}}</td>
</tr>
</template>
</vue - virtual - scroll - list>
</div>
</template>
<script>
import VueVirtualScrollList from 'vue - virtual - scroll - list';
export default {
components: {
VueVirtualScrollList
},
data() {
return {
tableData: [],
columns: []
};
}
};
</script>
- 批量更新:使用
nextTick
或类似机制,将多次数据更新合并为一次。例如在 Vue 中:
this.$nextTick(() => {
this.tableData = newData;
this.columns = newColumns;
});
- 防抖和节流:对于筛选、排序等频繁触发的操作,使用防抖或节流。以防抖为例,使用
lodash
的 debounce
函数:
import { debounce } from 'lodash';
export default {
methods: {
handleFilter: debounce(function() {
// 筛选逻辑
}, 300)
}
};
组件间通信方式
- 父子组件通信:
- 父传子:通过 props 传递数据,如表格数据、列配置等。
<template>
<TableComponent :tableData="tableData" :columns="columns"></TableComponent>
</template>
<script>
import TableComponent from './TableComponent.vue';
export default {
components: {
TableComponent
},
data() {
return {
tableData: [],
columns: []
};
}
};
</script>
- 子传父:通过事件,如分页、排序、筛选操作完成后通知父组件。
<!-- TableComponent.vue -->
<template>
<button @click="handleSort">排序</button>
</template>
<script>
export default {
methods: {
handleSort() {
this.$emit('sort - changed', newSortConfig);
}
}
};
</script>
<!-- 父组件 -->
<template>
<TableComponent @sort - changed="handleSortChange"></TableComponent>
</template>
<script>
import TableComponent from './TableComponent.vue';
export default {
components: {
TableComponent
},
methods: {
handleSortChange(sortConfig) {
// 处理排序变化
}
}
};
</script>
- 兄弟组件通信:通过一个共同的父组件作为中间人。例如,筛选组件和表格组件是兄弟组件,筛选组件将筛选条件传递给父组件,父组件再将筛选后的数据传递给表格组件。
<!-- 筛选组件 -->
<template>
<button @click="handleFilter">筛选</button>
</template>
<script>
export default {
methods: {
handleFilter() {
this.$emit('filter - changed', newFilterConfig);
}
}
};
</script>
<!-- 父组件 -->
<template>
<FilterComponent @filter - changed="handleFilterChange"></FilterComponent>
<TableComponent :tableData="filteredTableData"></TableComponent>
</template>
<script>
import FilterComponent from './FilterComponent.vue';
import TableComponent from './TableComponent.vue';
export default {
components: {
FilterComponent,
TableComponent
},
data() {
return {
originalTableData: [],
filteredTableData: []
};
},
methods: {
handleFilterChange(filterConfig) {
// 根据筛选条件过滤数据
this.filteredTableData = filter(this.originalTableData, filterConfig);
}
}
};
</script>