赞
踩
参考:vue3 二次封装element-plus 表格组件_vue3 + ts+elementui-plus 封装表格分页组件-CSDN博客
组件封装index.vue:
<template> <el-table v-loading="listLoading" :data="tableData" element-loading-text="Loading" fit border highlight-current-row :max-height="maxHeight" :cell-style="tableRowStyle" @row-click="clickRow" @selection-change="handleSelectionChange" :border="true" ref="table" @cell-click="showUnitInput" > <el-table-column type="selection" width="55" /> <el-table-column v-for="(item, index) in tableHeader" :key="index" :prop="item.prop" align="center" :label="item.label" :min-width="item.minWidth" > <template #default="scope"> <!-- 按钮 --> <div v-if="item.btn"> <el-button v-for="(k, index) in item.btn" :key="index" size="small" @click="k.func(scope.$index, scope.row)" >{{ k.name }}</el-button > </div> <!-- 图片 --> <div v-else-if="item.type == 'img'"> <el-image style="width: 100px; height: 100px" :src="scope.row.image" :fit="fit" /> </div> <!-- 数据字典转换 --> <div v-else-if="item.type == 'dic'"> <!-- <el-link v-if="item.isline == true" :type="item.lineType(scope.row[item.prop])" :underline="false" >{{ item.formatData(scope.row[item.prop]) }}</el-link > --> <div v-for="(ite, index) in listData[item.prop]"> <el-link v-if="scope.row[item.prop] == ite.key && item.isline == true" :type="ite.type" >{{ ite.value }}</el-link > <span v-else-if="scope.row[item.prop] == ite.key">{{ ite.value }}</span> </div> </div> <!-- 编辑 --> <div v-else-if="item.type == 'edit'"> <input type="text" v-model="scope.row[item.prop]" v-focus v-if=" tableRowEditId === scope.row.id && tableColumnEditIndex === scope.column.id " @blur="blurUnitInput(row, column)" @keyup.enter="blurUnitInput(row, column)" /> <span v-else>{{ scope.row[item.prop] }}</span> </div> <!-- 日期拼接、普通字段 --> <div v-else> <span v-if="!item.formatData"> <span v-if="item.isDate == true" >{{ repString(scope.row[item.prop[0]]) }}-{{ repString(scope.row[item.prop[1]]) }}</span > <span v-else>{{ scope.row[item.prop] }}</span> </span> <span v-else> <span>{{ scope.row[k.prop] }}</span> </span> </div> </template> </el-table-column> </el-table> <div class="demo-pagination-block"> <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 20, 30, 50]" :small="small" :disabled="disabled" :background="background" layout="total, sizes, prev, pager, next, jumper" :total="400" @size-change="handleSizeChange" @current-change="handleCurrentChange" style="float: right" /> </div> </template> <script lang="ts"> import { getCurrentInstance, ref } from "vue"; export default { props: { tableData: { type: Array, default: () => [], }, tableHeader: { type: Array, default: () => [], }, listLoading: { type: Boolean, default: false, }, maxHeight: { type: String, default: "", }, listData: { type: Object, default: {}, }, }, setup(props) { console.log(props.listData); const { proxy } = getCurrentInstance(); const selectValue = ref(null); const currentPage = ref(1); const pageSize = ref(10); const small = ref(false); const background = ref(false); const disabled = ref(false); const tableRowEditId = ref(0); const tableColumnEditIndex = ref(0); //图片平铺 const fit = ref("fill"); //对日期进行截取 function repString(val) { return val.substr(0, 10); } const blurUnitInput = (row: any, column: any) => { console.log(row, column); tableRowEditId.value = null; tableColumnEditIndex.value = null; //在此处调接口传数据 }; const tableRowStyle = ({ row }) => { let arr = []; if (selectValue.value !== null) { selectValue.value.filter((item, index) => { arr.push(item.id); }); } for (var i = 0; i <= arr.length; i++) { if (arr[i] == row.id) { return { backgroundColor: "#ebf5ff !important" }; } } }; // 点击其他位置也选中当前行 const clickRow = (row) => { console.log(row); proxy.$refs.table.toggleRowSelection(row, undefined); }; function handleSizeChange(val) { console.log(val); } function handleCurrentChange(val) { console.log(val); } // 多选框选中数据 function handleSelectionChange(selection) { console.log(selection); selectValue.value = selection; } const showUnitInput = (row: any, column: any) => { // console.log('row', row) // console.log('column', column) //赋值给定义的变量 tableRowEditId.value = row.id; //确定点击的单元格在哪行 如果数据中有ID可以用ID判断,没有可以使用其他值判断,只要能确定是哪一行即可 tableColumnEditIndex.value = column.id; //确定点击的单元格在哪列 }; return { repString, tableRowStyle, clickRow, handleSelectionChange, selectValue, currentPage, pageSize, handleSizeChange, handleCurrentChange, small, background, disabled, blurUnitInput, tableRowEditId, tableColumnEditIndex, fit, showUnitInput, }; }, }; </script> <style lang="scss"> .ipt { border: 0px; } </style>
组件使用tableDemo.vue:
- <template>
- <div class="app-container">
- <Ltable
- :tableData="list"
- :tableHeader="tableHeader"
- :listLoading="listLoading"
- :maxHeight="maxHeight"
- :listData="listData"
- ></Ltable>
- </div>
- </template>
-
- <script lang="ts" setup>
- import Ltable from "@/components/commonTable/index.vue";
- import { ref, reactive, nextTick, onMounted, toRefs } from "vue";
- import { useRouter } from "vue-router";
- import { ElMessage } from "element-plus";
-
- const router = useRouter();
- const state = reactive({
- // 模拟数据
- list: [
- {
- id: "123456",
- votethemeTitle: "dh",
- userName: "yp",
- votethemeStart: "2024-01-01",
- votethemeEnd: "2024-01-02",
- worksCount: "带钢",
- image:
- "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
- votethemeStatus: "1",
- },
- {
- id: "1234567",
- votethemeTitle: "dh",
- userName: "yp",
- votethemeStart: "2024-01-01",
- votethemeEnd: "2024-01-02",
- worksCount: "带钢",
- image:
- "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
- votethemeStatus: "3",
- },
- {
- id: "12345678",
- votethemeTitle: "dh",
- userName: "yp",
- votethemeStart: "2024-01-01",
- votethemeEnd: "2024-01-02",
- worksCount: "带钢",
- image:
- "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg",
- votethemeStatus: "2",
- },
- ],
- page: {},
- listLoading: false,
- // 表头
- tableHeader: [
- {
- prop: "id",
- label: "编号",
- minWidth: "50px",
- },
- {
- prop: "votethemeTitle",
- label: "主题名称",
- minWidth: "150px",
- type: "edit",
- },
- {
- prop: "userName",
- label: "发布人",
- minWidth: "80px",
- },
- {
- prop: ["votethemeStart", "votethemeEnd"],
- label: "活动时间",
- minWidth: "210px",
- isDate: true,
- },
- {
- prop: "worksCount",
- label: "参与作品",
- minWidth: "80px",
- },
- {
- prop: "image",
- label: "图片",
- minWidth: "120px",
- type: "img",
- },
- {
- prop: "votethemeStatus",
- label: "状态",
- minWidth: "80px",
- isline: true,
- type: "dic",
- },
- {
- prop: "btn",
- label: "操作",
- minWidth: "120px",
- btn: [
- {
- name: "查看",
- func: handleLook,
- },
- {
- name: "编辑",
- func: handleEdit,
- },
- ],
- },
- ],
- maxHeight: "calc(100vh - 322px)",
- });
- // 模拟数据字典数据
- const votethemeStatus = ref([
- { key: 1, value: "未开始", type: "" },
- { key: 2, value: "进行中", type: "primary" },
- { key: 3, value: "已结束", type: "danger" },
- ]);
- let listData = reactive({});
- listData["votethemeStatus"] = votethemeStatus;
- const { list, page, listLoading, tableHeader, maxHeight } = toRefs(state);
-
- onMounted(() => {
- // fetchData()
- });
- // 按钮事件
- function handleEdit(index, row) {
- console.log(row);
- }
- function handleLook(index, row) {
- router.push({
- path: "detail?id=" + row.id,
- });
- }
- </script>
- <style></style>
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。