赞
踩
前期回顾
目录
封装了一个子组件(table、分页),在不同页面引入
分页、表格排序、文字居中、溢出隐藏、操作列、开关、宽、最小宽、type类型(selection/index/expand)、格式化 、不同页面不同操作列、vuex、vue持久化插件、
说思路:data数据请求接口拿到,表头数据一般也是后台接口,如没,前台可自定义自己写
- //lable指定表头名 //prop指定每一项数据
- <el-table :data="tableData">
- <el-table-column
- :label="item.label"
- :prop="item.prop"
- :key="index" v-for="(item,index) in tableHeader"
- >
- </el-table-column>
- </el-table>
-
-
- //表头
- tableHeader:[
- {label:'姓名' , prop : 'uname'},
- {label:'年龄' , prop : 'age'},
- {label:'性别' , prop : 'sex'},
- ],
-
- //表数据
- tableData:[
- {uname:"小明",age:'20',sex:'男'},
- {uname:"小黑",age:'18',sex:'男'},
- ]
-
-
念及此!那开始正文
- <template>
- <div class="container">
- <el-card shadow="hover">
- <el-scrollbar max-height="300px" v-if="isShowSearchRegion" class="wrap">
- <slot name="search"></slot>
- </el-scrollbar>
- <el-table
- v-bind="$attrs"
- stripe
- style="width: 100%"
- :data="tableData"
- :border="tableBorder"
- :height="excludeSearchAreaAfterTableHeight"
- >
- <template #empty>
- <el-empty :image-size="emptyImgSize" description="暂无数据" />
- </template>
-
- <el-table-column
- type="index"
- label="序号"
- min-width="60"
- :index="orderHandler"
- align="center"
- />
-
- <el-table-column
- v-for="item in tableHeader"
- v-bind="item"
- :key="item.prop"
- >
- <template #default="{ row }" v-if="item.slotKey">
- <template v-if="item.slotKey.includes('default')">
- <el-link
- type="primary"
- :underline="false"
- @click="handleEdit(row)"
- >编辑</el-link
- >
- <el-popconfirm
- title="确定删除吗?"
- @confirm="handleDelete(row.id)"
- >
- <template #reference>
- <el-link class="ml15" type="danger" :underline="false"
- >删除</el-link
- >
- </template>
- </el-popconfirm>
- </template>
- <slot
- v-for="slot in item.slotKey.split(',')"
- :name="slot"
- :row="row"
- ></slot>
- </template>
- </el-table-column>
- </el-table>
-
- <!-- 分页 -->
- <el-pagination
- v-if="paginationFlag"
- background
- :page-sizes="pageSizesArr"
- :current-page="pageNum"
- :page-size="pageSize"
- :layout="layout"
- :total="total"
- @size-change="handleSizeChange"
- @current-change="handleCurrentChange"
- ></el-pagination>
- </el-card>
- </div>
- </template>
-
- <script setup lang="ts">
- import { onMounted, ref } from "vue";
- import myEmits from "./newTableConfig/emits";
- import myProps from "./newTableConfig/props";
-
- const emits = defineEmits(myEmits);
- const props = defineProps(myProps);
-
- // 序号根据数据长度计算
- const orderHandler = (index: number) => {
- const { pageNum, pageSize } = props;
- // 第0条 * 每页条数 + 当前索引+1
- return (pageNum - 1) * pageSize + index + 1;
- };
- // 页数改变
- const handleSizeChange = (val: number | string) =>
- emits("handleSizeChange", val);
-
- // 当前页改变
- const handleCurrentChange = (val: number | string) =>
- emits("handleCurrentChange", val);
-
- // 编辑、删除
- const handleEdit = (row: object) => emits("handleEdit", row);
- const handleDelete = (id: number) => emits("handleDelete", id);
-
- // 搜索区域高度及默认值
- const Height = ref();
- // 减去搜索区域高度后的table
- const excludeSearchAreaAfterTableHeight = ref("calc(100vh - 165px)");
-
- // 获取表格高度-动态计算搜索框高度(onMounted、resize,208是已知的面包屑tebView高度)
- const updateHeight = () => {
- let wrapEl = document.querySelector(".wrap") as HTMLDivElement | null;
- if (!wrapEl) return;
- Height.value = wrapEl.getBoundingClientRect().height;
- if (props.isShowSearchRegion) {
- excludeSearchAreaAfterTableHeight.value = `calc(100vh - ${
- 165 + Height.value
- }px)`;
- }
- };
- onMounted(() => {
- // 表格下拉动画
- const tableContainer = <HTMLElement>document.querySelector(".container");
- setTimeout(() => {
- if (tableContainer) tableContainer.style.transform = "translateY(0)";
- updateHeight();
- }, 300);
- });
- window.addEventListener("resize", updateHeight);
- </script>
-
- <style scoped lang="scss">
- .container {
- padding: 15px;
- transform: translateY(-100%);
- transition: transform 0.5s;
- // background-color: #870404;
- background-color: #f8f8f8;
- .el-scrollbar {
- // border: 1px solid pink;
- min-height: 100px;
- width: 100%;
- height: fit-content;
- }
- .el-card {
- width: 100%;
- height: 100%;
- }
-
- .el-pagination {
- margin-left: 15%;
- height: 35px;
- margin-top: 16px;
- }
- }
- // 穿透父组件
- :deep(.el-link) {
- padding-left: 10px;
- }
- </style>
- export default [
- // 这里是自定义事件 emits
- 'handleSizeChange',
- 'handleCurrentChange',
- 'handleEdit',
- 'handleDelete',
- ];
- export default {
- // 表头数据
- tableHeader: {
- type: Array as () => TableHeader[],
- default: function () {
- return [];
- },
- },
-
- // 表格显示的数据
- tableData: {
- default: function () {
- return [];
- },
- },
-
- // 边框
- tableBorder: {
- type: Boolean,
- default: false,
- },
-
- // 总页数
- total: {
- type: Number,
- default: 0,
- },
-
- // 分页的页容量数组
- pageSizesArr: {
- type: Array as () => number[],
- default() {
- return [10, 20, 30, 50];
- },
- },
-
- // 分页的布局
- layout: {
- type: String,
- default: 'total, sizes, prev, pager, next, jumper',
- },
-
- // 分页是否显示
- paginationFlag: {
- type: Boolean,
- default: true,
- },
- // 当前页
- pageNum: {
- type: Number,
- default: 1,
- },
- // 页容量
- pageSize: {
- type: Number,
- default: 10,
- },
- // empty的图片大小
- emptyImgSize: {
- type: Number,
- default: 200,
- },
- // 搜索区域是否显示
- isShowSearchRegion: {
- type: Boolean,
- default: true,
- },
-
- // 是否展示连续序号
- isSerialNo: {
- type: Boolean,
- default: true,
- },
- };
-
- // new-table
- //表头数据类型定义
- declare interface TableHeader<T = any> {
- label: string;
- prop: string;
- align?: string;
- overHidden?: boolean;
- minWidth?: string;
- sortable?: boolean;
- type?: string;
- fixed?: string;
- width?: string;
- isActionColumn?: boolean;
- isCustomizeColumn?: boolean;
- slotKey?: string;
- }
-
- /*
- 允许任何字符串作为索引
- 不然会报错, 使用动态属性名,需要使用索引签名
- */
- declare type SearchFormType = {
- [key: string]: string;
- };
-
- declare type FormOptions = {
- type: string;
- props: {
- label: string;
- placeholder: string;
- type: string;
- clearable: boolean;
- };
- vm: string;
- selectOptions?: [
- {
- value: string | number;
- label: string;
- }
- ];
- cascaderOptions?: any;
- };
- /* 全局样式 个人不允许修改全局样式【重要!!!】*/
-
- /* 开关样式
- ------------------------------------------------ */
-
- .el-switch__label--left {
- position: relative;
- left: 45px;
- color: #fff;
- z-index: -1111;
- }
-
- .el-switch__core {
- width: 50px !important;
- }
-
- .el-switch__label--right {
- position: relative;
- right: 46px;
- color: #fff;
- z-index: -1111;
- }
-
- .el-switch__label--right.is-active {
- z-index: 1111;
- color: #fff !important;
- }
-
- .el-switch__label--left.is-active {
- z-index: 1111;
- color: #fff !important;
- }
-
-
- /* 表格样式
- ------------------------------------------------ */
- .el-table thead tr,
- .el-table tbody tr>td {
- padding: 0 !important;
- height: 75px;
- line-height: 75px;
- color: #909399;
- }
-
- .el-table thead tr>th {
- background-color: var(--el-color-info-light-8) !important;
- }
- <template>
- <el-form ref="searchFormRef" :model="searchForm" size="default">
- <!-- 使用了不稳定的 key,可能会导致一些不可预期的行为,比如输入框失去焦点。 -->
- <el-row>
- <el-col
- :xs="24"
- :sm="24"
- :md="24"
- :lg="12"
- :xl="6"
- v-for="item in formOptions"
- :key="item.vm"
- >
- <el-form-item :label="item.props.label" :prop="item.vm">
- <el-input
- v-if="item.type === FormOptionsType.INPUT"
- v-model.lazy="searchForm[item.vm]"
- v-bind="item.props"
- class="ml10 w100"
- ></el-input>
-
- <el-select
- v-if="item.type === FormOptionsType.SELECT"
- v-model.lazy="searchForm[item.vm]"
- v-bind="item.props"
- class="ml10 w100"
- >
- <el-option
- v-for="option in item.selectOptions"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
-
- <el-cascader
- v-if="item.type === FormOptionsType.CASCADER"
- v-model.lazy="searchForm[item.vm]"
- :options="item.cascaderOptions"
- v-bind="item.props"
- class="ml10 w100"
- />
-
- <el-date-picker
- v-if="item.type === FormOptionsType.DATE_PICKER"
- v-model.lazy="searchForm[item.vm]"
- v-bind="item.props"
- class="ml10 w100"
- />
- </el-form-item>
- </el-col>
- <el-col :xs="24" :sm="24" :md="24" :lg="12" :xl="6" class="xs-mt">
- <el-form-item style="margin-left: 10px">
- <el-button @click="onReset">
- <SvgIcon name="ant-ReloadOutlined"></SvgIcon>
- 重置
- </el-button>
- <el-button type="primary" @click="onSearch">
- <SvgIcon name="ant-SearchOutlined"></SvgIcon>
- 查询
- </el-button>
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </template>
-
- <script setup lang="ts" name="newForm">
- import { toRefs, onBeforeUnmount, ref } from 'vue';
- import type { PropType } from 'vue';
- import { type FormInstance } from 'element-plus';
-
- const searchFormRef = ref<FormInstance>();
-
- enum FormOptionsType {
- INPUT = 'input', // 输入框
- SELECT = 'select', // 下拉框
- CASCADER = 'cascader', // 级联选择器
- DATE_PICKER = 'date-picker', // 日期选择器
- }
-
- const props = defineProps({
- formOptions: {
- type: Array as PropType<FormOptions[]>,
- required: true,
- },
- searchForm: {
- type: Object as PropType<SearchFormType>,
- required: true,
- },
- });
- const { formOptions, searchForm } = toRefs(props);
-
- const emit = defineEmits(['reset', 'search']);
-
- const onReset = () => emit('reset');
- const onSearch = () => emit('search');
- onBeforeUnmount(() => searchFormRef.value?.resetFields());
- defineExpose({ searchFormRef });
- </script>
-
- <style scoped lang="scss">
- :deep(.el-form-item__label) {
- margin-left: 10px;
- }
- </style>
封装完成,下面在使用的页面调用
- <template>
- <div class="container-wrapper">
- <!-- 动态 page -->
- <new-table
- :tableHeader="tableHeader"
- :tableData="tableData"
- :pageNum="pageNum"
- :pageSize="pageSize"
- :total="pageTotal"
- @handleSizeChange="onHandleSizeChange"
- @handleCurrentChange="onHandleCurrentChange"
- @handleEdit="onHandleEdit"
- @handleDelete="onHandleDelete"
- >
- <template #search>
- <new-form
- :formOptions="formOptions"
- :searchForm="searchForm"
- @reset="onReset"
- @search="onSearch"
- />
- </template>
-
- <template #switch="{ row }">
- <el-switch
- v-model="row.fileStatus"
- active-text="开"
- inactive-text="关"
- :active-value="1"
- :inactive-value="2"
- active-color="#13ce66"
- inactive-color="#ff4949"
- @change="changeSwitchStatus(row.id, row.fileStatus)"
- />
- </template>
- </new-table>
- </div>
- </template>
-
- <script setup lang="ts" name="algorithmRegistrationQuery">
- import { onMounted, reactive, toRefs } from "vue";
- // import { getTestList } from "/@/api/encryptionAlgorithm/templateDefinition";
- // import { STATUS_CODE } from "/@/enum/global";
- const state = reactive({
- //表头数据
- // el-table-column有的属性都可以在这传
- tableHeader: <TableHeader[]>[
- { label: "姓名", prop: "uname" },
- { label: "年龄", prop: "age" },
- { label: "性别", prop: "sex", slotKey: "switch" },
- { label: "操作", fixed: "right", slotKey: "default" },
- ],
- //表项数据
- tableData: [
- { uname: "小帅", age: "18", sex: "男", status: false, id: 1 },
- { uname: "小美", age: "148", sex: "女", status: false, id: 2 },
- { uname: "小明", age: "12", sex: "男", status: true, id: 3 },
- { uname: "小红", age: "12", sex: "女", status: false, id: 4 },
- { uname: "小黑", age: "12", sex: "男", status: true, id: 5 },
- { uname: "小白", age: "12", sex: "女", status: false, id: 6 },
- { uname: "小黑", age: "12", sex: "男", status: true, id: 7 },
- { uname: "小白", age: "12", sex: "女", status: false, id: 8 },
- { uname: "小黑", age: "12", sex: "男", status: true, id: 9 },
- { uname: "小白", age: "12", sex: "女", status: false, id: 10 },
- { uname: "小黑", age: "12", sex: "男", status: true, id: 11 },
- ],
- formOptions: <FormOptions[]>[
- {
- type: "input",
- props: {
- label: "合规规则",
- placeholder: "请输入合规规则",
- type: "text",
- clearable: true,
- },
- vm: "knowledgeName",
- },
- {
- type: "input",
- props: {
- label: "文件数量",
- placeholder: "请输入文件数量",
- type: "text",
- clearable: true,
- },
- vm: "documentNumber",
- },
- // 下拉选择器
- {
- type: "select",
- props: {
- label: "所属部门",
- placeholder: "请选择",
- clearable: true,
- },
- vm: "department",
- selectOptions: [
- {
- label: "数据安全",
- value: 1,
- },
- {
- label: "研发",
- value: 2,
- },
- {
- label: "事业",
- value: 3,
- },
- ],
- },
- // 时间范围选择器
- {
- type: "date-picker",
- props: {
- label: "时间范围",
- type: "datetimerange", // datetimerange范围 datetime日期
- clearable: true,
- "range-separator": "-",
- "start-placeholder": "开始日期",
- "end-placeholder": "结束日期",
- "value-format": "YYYY-MM-DD HH:mm:ss",
- },
- vm: "createTime",
- },
-
- // 级联选择器
- {
- type: "cascader",
- props: {
- label: "所属部门",
- placeholder: "请选择",
- clearable: true,
- },
- vm: "cascader",
- cascaderOptions: [
- {
- value: "guide",
- label: "Guide",
- children: [
- {
- value: "disciplines",
- label: "Disciplines",
- children: [
- {
- value: "consistency",
- label: "Consistency",
- },
- ],
- },
- {
- value: "navigation",
- label: "Navigation",
- children: [
- {
- value: "side nav",
- label: "Side Navigation",
- },
- {
- value: "top nav",
- label: "Top Navigation",
- },
- ],
- },
- ],
- },
- {
- value: "component",
- label: "Component",
- children: [
- {
- value: "basic",
- label: "Basic",
- children: [
- {
- value: "button",
- label: "Button",
- },
- ],
- },
- {
- value: "form",
- label: "Form",
- children: [
- {
- value: "radio",
- label: "Radio",
- },
- {
- value: "checkbox",
- label: "Checkbox",
- },
- ],
- },
- {
- value: "data",
- label: "Data",
- children: [
- {
- value: "table",
- label: "Table",
- },
- ],
- },
- {
- value: "notice",
- label: "Notice",
- children: [
- {
- value: "alert",
- label: "Alert",
- },
- ],
- },
- {
- value: "navigation",
- label: "Navigation",
- children: [
- {
- value: "menu",
- label: "Menu",
- },
- ],
- },
- {
- value: "others",
- label: "Others",
- children: [
- {
- value: "dialog",
- label: "Dialog",
- },
- ],
- },
- ],
- },
- {
- value: "resource",
- label: "Resource",
- children: [
- {
- value: "axure",
- label: "Axure Components",
- },
- ],
- },
- ],
- },
- ],
- //这里允许动态属性所以可为空
- searchForm: <SearchFormType>{},
- pageNum: 1,
- pageSize: 10,
- pageTotal: 0,
- });
- const {
- tableHeader,
- tableData,
- formOptions,
- searchForm,
- pageNum,
- pageSize,
- pageTotal,
- } = toRefs(state);
-
- // 修改
- const onHandleEdit = (row: object) => {
- console.log(row);
- };
-
- // 删除
- const onHandleDelete = (row: object) => {
- console.log(row);
- };
-
- // switch
- const changeSwitchStatus = (id: number, status: boolean) => {
- console.log(id, status);
- };
-
- //页容量改变
- const onHandleSizeChange = (val: number) => {
- // console.log('页容量 ==>:', val);
- pageSize.value = val;
- getTableList(pageNum.value, pageSize.value);
- };
- //当前分页改变
- const onHandleCurrentChange = (val: number) => {
- // console.log('当前页 声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/701537推荐阅读
相关标签
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。