基于Vue3和Element Plus实现可扩展的表格组件
作者:阳光的男夹克
在开发过程中,我们经常需要创建具有复杂功能的表格组件,本文将介绍如何使用 Vue 3 和 Element Plus 库来构建一个可扩展的表格组件,文中有详细的代码示例供大家参考,需要的朋友可以参考下
引言
在开发过程中,我们经常需要创建具有复杂功能的表格组件。本文将介绍如何使用 Vue 3 和 Element Plus 库来构建一个可扩展的表格组件,包括增加自定义插槽、操作栏按钮以及动态列内容。
组件概述
我们将创建一个名为 Table
的 Vue 组件,该组件具有以下特性:
- 支持固定表头和边框
- 可配置的列宽和最小列宽
- 支持树形数据和展开行
- 自定义列内容和操作栏按钮
- 动态计算表格高度
以下是组件的实现步骤和代码示例。
组件实现
1. 组件模板
首先,我们定义组件的模板部分,使用 el-table
组件来创建表格,并添加三个自定义插槽:default
、operationsStart
和 operationsEnd
。
<template> <el-table border stripe :data="data" :height="tableHeight" table-layout="fixed" :row-key="rowKey" :highlight-current-row="highlightCurrentRow" :tree-props="treeProps" :header-cell-style="{ background: '#f5f7fa', color: '#606266', fontSize: '13px', }" @selection-change="handleSelectionChange" :v-loading="loading" :row-class-name="tableRowClassName" :expand-row-keys="expandRowKeys" class="absolute" > <el-table-column v-if="showSelection" align="center" fixed type="selection" width="55" /> <el-table-column v-for="tableModel in tableModels" :key="tableModel.key" :prop="tableModel.key" :label="tableModel.label" :width="tableModel.width" :min-width="tableModel.minWidth" :align="tableModel.align" :header-align="tableModel.headerAlign" > <template #default="{ row }"> <slot v-if="slots[tableModel.key]" :name="tableModel.key" v-bind="row" ></slot> <span v-else> {{ row[tableModel.key] }} </span> </template> </el-table-column> <el-table-column fixed="right" label="操作" :width="operationsWidth" :min-width="minWidth" :align="operationsAlign" :header-align="operationsHeaderAlign" v-if="shoeOperations" > <template #default="{ row, $index }"> <slot name="operationsStart" v-bind="row"></slot> <el-button link type="primary" :icon="Edit" @click="handleEdit(row, $index)" :v-hasPerm="editHasPerm" v-if="showEditBtn" >编辑 </el-button> <el-button @click="handleDelete(row, $index)" link type="danger" :icon="Delete" v-if="showDeleteBtn" :v-hasPerm="deleteHasPerm" >删除 </el-button> <slot name="operationsEnd" v-bind="row"></slot> </template> </el-table-column> </el-table> </template>
2. 组件脚本
在脚本部分,我们定义了组件的 props、slots 和 emits,以及一些必要的响应式数据和函数。
<script setup lang="ts"> // 使用 unknown 类型表示任何值 type MyUnknownType = unknown; /* * @slot default 插槽 * operationsStart 从操作栏开头增加按钮 * operationsStart 从操作栏结尾增加按钮 * Key TableModel里面的Key,用来自定义列的内容 * */ import { Delete, Edit } from '@element-plus/icons-vue'; // 【接口】table表格模型 interface ITableModel { // 表头显示文字 label: string; // 表格列Keu key: string; // 表格列宽 width?: number | string; // 表格列显示文字 value?: string; // 表格内容位置 align?: string; // 表格表头位置 headerAlign?: string; // 列最小宽度 minWidth?: number | string; } // 【接口】接受传参字段 interface IProps { // 生成表格参数 tableModels?: ITableModel[]; // 表格数据 data: object[]; // 是否为树形表格 treeProps?: unknown; // 加载状态 loading?: boolean; // 表格行Keu rowKey?: any; // 表格高度 height?: any; // 表格自适应减去的高度 // eslint-disable-next-line vue/prop-name-casing dynamic?: number; // 表格单选 highlightCurrentRow?: boolean; // 是否显示编辑按钮 showEditBtn?: boolean; // 是否显示多选框 showSelection?: boolean; // 是否显示删除按钮 showDeleteBtn?: boolean; // 删除权限 deleteHasPerm?: any; // 编辑权限 editHasPerm?: any; // 操作栏宽度 operationsWidth?: number; // 是否显示操作栏 shoeOperations?: boolean; // 操作栏内容位置 operationsAlign?: string; // 操作栏头部位置 operationsHeaderAlign?: string; // 操作栏最小宽度 minWidth?: number | string; // 树表格时默认展开参数 expandRowKeys?: any; } // 【接口】分页 interface IPage { // 当前页 pageNum: number; // 每页显示条数 pageSize: number; } // 初始化默认参数 const props = withDefaults(defineProps<IProps>(), { loading: false, rowKey: 'id', dynamic: 0, showEditBtn: true, highlightCurrentRow: false, showSelection: false, showDeleteBtn: true, deleteHasPerm: [], editHasPerm: [], tableModels: () => [], treeProps: () => [], shoeOperations: true, operationsWidth: 150, operationsAlign: 'center', operationsHeaderAlign: 'center', expandRowKeys: [], minWidth: 'auto', height: 'auto' }); // 插槽对象 const slots = useSlots(); // 定义组件发出的事件 const emit = defineEmits(['handleEdit', 'handleDelete', 'handlePagination', 'handleSelectionChange', 'handlePage']); const tableHeight = ref<any>(); // watch监听动态计算table的高度,根据dynamic是否大于0,dynamic层级大于height watch( [() => props.height, () => props.dynamic], ([height, dynamic]) => { if (height && !dynamic) { tableHeight.value = height; } else if ((!height && dynamic) || (height && dynamic)) { // 获取浏览器窗口高度 const windowHeight = window.innerHeight; tableHeight.value = windowHeight - dynamic; } else { tableHeight.value = 'auto'; } }, { deep: true, immediate: true } ); // 增加样式Class const tableRowClassName = ({ row, rowIndex }: { row: Object; rowIndex: number }) => { if (rowIndex % 2 === 1) { return 'warning-row'; } return ''; }; // 点了多选 const handleSelectionChange = (val: ITableModel[]) => { emit('handleSelectionChange', val); }; // 点击了编辑 const handleEdit = (data: object, index: number) => { emit('handleEdit', data, index); }; // 点击了删除 const handleDelete = (data: object, index: number) => { emit('handleDelete', data, index); }; </script>
3. 使用案例
以下是如何在父组件中使用 Table
组件的示例,包括自定义列内容和操作栏按钮。
<Table :dynamic="dynamicHeight" :tableModels="table.tableModels" :data="table.data" :loading="table.loading" :showSelection="table.showSelection" :operationsWidth="table.operationsWidth" @handle-edit="openDialog" @handle-delete="handleDelete" @handle-selection-change="handleSelectionChange" > <!-- 自定义列【status】字段 --> <template #status="scope"> <el-tag size="small" v-if="scope.status === 1" type="success"> 正常 </el-tag> <el-tag size="small" v-else type="info">禁用</el-tag> </template> <!-- 操作栏从开头增加按钮 --> <template #operationsStart="scope"> <el-button type="primary" size="small" link :icon="Position" @click="openMenuDialog(scope)" > 分配权限 </el-button> </template> </Table>
4. 渲染表格的数据
最后,我们定义表格的列模型和数据。
const table = reactive({ tableModels: [ { label: "角色名称", key: "name", align: "left", headerAlign: "center", value: "name", minWidth: 200, }, { label: "角色编码", key: "code", width: 200, align: "center", headerAlign: "center", value: "code", }, { label: "数据权限", key: "dataScope", width: 200, align: "center", headerAlign: "center", value: "dataScope", }, { label: "状态", key: "status", width: 200, align: "center", headerAlign: "center", value: "status", }, { label: "排序", key: "sort", width: 200, align: "center", headerAlign: "center", value: "sort", }, ], data: [] as any[], showSelection: true, operationsWidth: 250, loading: false, });
结论
通过以上步骤,我们创建了一个功能丰富、可扩展的表格组件。这个组件可以根据实际需求调整列配置、操作按钮和自定义内容,非常适合在复杂的应用场景中使用。
以上就是基于Vue3和Element Plus实现可扩展的表格组件的详细内容,更多关于Vue3 Element Plus表格组件的资料请关注脚本之家其它相关文章!