首页>>前端>>Vue->Vue3.2 + Element

Vue3.2 + Element

时间:2023-11-30 本站 点击:0

前言 ?

在公司经常接触到后台管理系统的开发,基本上 90% 以上都是 table 页面,业务逻辑也基本上一样。刚开始也想的是找一个基于 element 二次封装的 el-table,在搜寻过程中也接触了很多优秀的项目,其中包括:(vxe-table、avue……)但是这些项目终归没有自己开发灵活,所有就诞生了我的 Pro-Table 组件 ???

? 请注意:以下内容只代表我个人封装思想,如果你觉得还不错,请帮我点个小小的 star,如果你有更好的想法,请在评论区留言,蟹蟹 ??

一、在线预览 ?

Link:http://admin.spicyboy.cn ✨

二、Git 仓库地址 (欢迎 Star⭐⭐⭐)

Gitee:https://gitee.com/laramie/Geeker-Admin ✨

GitHub:https://github.com/HalseySpicy/Geeker-Admin ✨

三、Pro-Table 功能 ???

表格内容自适应屏幕宽高,溢出内容表格内部滚动。

表格数据操作 Hooks (单条数据删除、批量删除、重置密码、状态切换……)

表格数据多选 Hooks (支持现跨页勾选数据)

表格序号累加排序

表格列排序、单元格内容格式化(根据字典自动格式化)

树形表格展示(后期会增加懒加载)

表格数据导入组件、导出钩子函数

表格查询(可携带初始参数)、重置功能的封装

表格分页模块封装(Pagination)

表格数据刷新、列显隐、搜索显隐设置

四、需求分析 ?

首先我们来看效果图(总共可以分为五个区域):

1、表格搜索区域

2、表格数据操作按钮区域

3、表格功能按钮区域

4、表格主体内容展示区域

5、表格分页区域

1、搜索区域分析:

可以看到搜索区域的字段都是存在于表格当中的,并且每个页面的搜索、重置方法都是一样的逻辑,只是不同的查询参数而已。我们完全可以在传表格配置项 columns 时,直接指定某个字段的 search:true 就能把该项变为搜索项,然后使用 SearchType 字段可以指定搜索框的类型,最后把表格的搜索方法都封装成 Hooks 钩子函数。页面上完全就不会存在搜索逻辑了。

2、表格数据操作按钮区域分析:

表格数据操作按钮基本上每个页面都会不一样,所以我们直接使用 作用域插槽 来完成每个页面的数据操作按钮区域,作用域插槽 可以将表格多选数据信息从 Pro-Table 的 Hooks 多选钩子函数中传到页面上使用。

3、表格功能按钮区域分析:

这块区域没什么特殊功能,只有三个按钮,其功能分别为:表格数据刷新(一直会携带当前查询和分页条件)、表格列显隐设置、表格搜索区域显隐(方便展示更多的数据信息)。 可通过 toolButton 属性控制这块区域的显隐。

4、表格主体内容展示区域分析:

这块区域主要就是数据展示,配置 columns 项传到 Pro-Table 组件中就行了。使用作用域插槽可以自定义每一列的显示自己需要的内容,还支持表格数据多选(内部已封装了多选 Hooks 钩子函数)。

5、表格分页区域分析:

分页也没有什么特殊的功能,该支持的都支持了。 ??

五、Pro-Table 文档

1、Pro-Table 属性配置:

字段字段类型是否必传默认值字段描述columnsColumnProps✅—Pro-Table 会根据此字段渲染搜索表单与表格列requestApiFunction✅—获取表格数据的请求函数paginationBoolean❌true是否显示分页组件initParamObject❌{}是否携带表格请求的初始化参数borderBoolean❌true是否带有纵向边框stripeBoolean❌false是否为斑马纹 tabletoolButtonBoolean❌true是否显示表格工具按钮区域childrenNameString❌children当表格为树形表格时,指定 children 字段名

2、ColumnProps 属性配置(都是可选参数):

字段字段类型默认值可选值字段描述typeString—index | selection | expand特殊类型(序号、多选、展开)propString——字段名称对应列内容的字段名labelString——表头标题widthNumber | String——单元格宽度enumObject——字典,可格式化单元格,还可以作为搜索框的下拉选项isShowBooleantrue—是否展示列sortableBooleanfalse—是否可以静态排序fixedString—left | right固定在表格左右tagBooleanfalse—是否为标签显示,可在 enum 里指定 tagType 类型imageBooleanchildren—是否为图片显示searchBooleanfalse—是否为搜索项searchTypeStringtexttext | select | multipleSelect | treeSelect | mutipleTreeSelect | date | timerange | datetimerange搜索项类型,默认为 textinitSearchParamString | Number | Boolean | Any[]——搜索项是否带初始化参数

六、代码实现?(详情去项目里查看,这里只贴了一部分代码)

1、Pro-table 组件:

Template:

<template><div class="table-box"><!-- 查询表单 --><SearchForm:search="search":reset="reset":searchParam="searchParam":columns="searchColumns"v-show="isShowSearch"</SearchForm><!-- 表格头部 操作按钮 --><div class="table-header"><div class="header-button-lf"><slot name="tableHeader" :ids="selectedListIds" :isSelected="isSelected"></slot></div><div class="header-button-ri" v-if="toolButton"><el-button :icon="Refresh" circle @click="getTableList"> </el-button><el-button :icon="Operation" circle @click="openColSetting"> </el-button><el-button :icon="Search" circle v-if="searchColumns.length" @click="isShowSearch = !isShowSearch"> </el-button></div></div><!-- 表格主体 --><el-tableheight="575"ref="tableRef":data="tableData":border="border"@selection-change="selectionChange":row-key="getRowKeys":stripe="stripe":tree-props="{ children: childrenName }"<template v-for="item in tableColumns" :key="item"><!-- selection || index --><el-table-columnv-if="item.type == 'selection' || item.type == 'index'":type="item.type":reserve-selection="item.type == 'selection'":label="item.label":width="item.width":fixed="item.fixed"</el-table-column><!-- expand(展开查看详情,请使用作用域插槽) --><el-table-columnv-if="item.type == 'expand'":type="item.type":label="item.label":width="item.width":fixed="item.fixed"v-slot="scope"<slot :name="item.type" :row="scope.row"></slot></el-table-column><!-- other --><el-table-columnv-if="item.prop && !item.type && item.isShow":prop="item.prop":label="item.label":width="item.width":sortable="item.sortable":show-overflow-tooltip="true":resizable="true":fixed="item.fixed"v-slot="scope"<!-- 自定义配置每一列 slot(作用域插槽) --><slot :name="item.prop" :row="scope.row"><!-- 图片(自带预览) --><el-imagev-if="item.image":src="scope.row[item.prop!]":preview-src-list="[scope.row[item.prop!]]"fit="cover"class="table-image"preview-teleported/><!-- tag 标签(自带格式化) --><el-tag v-else-if="item.tag" :type="filterEnum(scope.row[item.prop!],item.enum,'tag')">{{ item.enum?.length ? filterEnum(scope.row[item.prop!],item.enum): defaultFormat(0,0,scope.row[item.prop!]) }}</el-tag><!-- 文字(自带格式化) --><span v-else>{{ item.enum?.length ? filterEnum(scope.row[item.prop!],item.enum): defaultFormat(0,0,scope.row[item.prop!]) }}</span></slot></el-table-column></template><template #empty><div class="table-empty"><img src="@/assets/images/notData.png" alt="notData" /><div>暂无数据</div></div></template></el-table><!-- 分页 --><Paginationv-if="pagination":pageable="pageable":handleSizeChange="handleSizeChange":handleCurrentChange="handleCurrentChange"</Pagination><!-- 列设置 --><ColSetting v-if="toolButton" ref="colRef" :tableRef="tableRef" :colSetting="colSetting"></ColSetting></div></template>

Script:

<script setup lang="ts" name="proTable">import { ref, onMounted } from "vue";import { useTable } from "@/hooks/useTable";import { useSelection } from "@/hooks/useSelection";import { Refresh, Operation, Search } from "@element-plus/icons-vue";import { ColumnProps } from "@/components/ProTable/interface";import { filterEnum, defaultFormat } from "@/utils/util";import SearchForm from "@/components/SearchForm/index.vue";import Pagination from "@/components/Pagination/index.vue";import ColSetting from "./components/ColSetting.vue";

const tableRef = ref();

// 是否显示搜索模块 const isShowSearch = ref(true);

interface ProTableProps { columns: Partial[]; // 列配置项 requestApi: (params: any) => Promise; // 请求表格数据的api ==> 必传 pagination?: boolean; // 是否需要分页组件 ==> 非必传(默认为true) initParam?: any; // 初始化请求参数 ==> 非必传(默认为{}) border?: boolean; // 表格是否显示边框 ==> 非必传(默认为true) stripe?: boolean; // 是否带斑马纹表格 ==> 非必传(默认为false) toolButton?: boolean; // 是否显示表格功能按钮 ==> 非必传(默认为true) childrenName?: string; // 当数据存在 children 时,指定 children key 名字 ==> 非必传(默认为"children") }

// 接受父组件参数,配置默认值 const props = withDefaults(defineProps(), { columns: () => [], pagination: true, initParam: {}, border: true, stripe: false, toolButton: true, childrenName: "children" });

// 表格多选 Hooks const { selectionChange, getRowKeys, selectedListIds, isSelected } = useSelection();

// 表格操作 Hooks const { tableData, pageable, searchParam, initSearchParam, getTableList, search, reset, handleSizeChange, handleCurrentChange } = useTable(props.requestApi, props.initParam, props.pagination);

// 表格列配置项处理(添加 isShow 属性,控制显示/隐藏) const tableColumns = ref<Partial[]>(); tableColumns.value = props.columns.map(item => { return { ...item, isShow: true }; });

// 过滤需要搜索的配置项 const searchColumns = props.columns.filter(item => item.search);

// 设置搜索表单的默认值 searchColumns.forEach(column => { if (column.initSearchParam !== undefined && column.initSearchParam !== null) { initSearchParam.value[column.prop!] = column.initSearchParam; searchParam.value[column.prop!] = column.initSearchParam; } });

// 列设置 const colRef = ref(); // 过滤掉不需要设置显隐的列 const colSetting = tableColumns.value.filter((item: Partial) => { return item.type !== "selection" && item.type !== "index" && item.type !== "expand"; }); const openColSetting = () => { colRef.value.openColSetting(); };

// 获取表格数据 onMounted(() => { getTableList(); });

// 暴露给父组件的参数和方法 defineExpose({ searchParam, refresh: getTableList });

````.

原文:https://juejin.cn/post/7094890833064755208


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/3740.html