Vue+ElementPlus实现动态表格

提示:Vue + Element-Plus 实现动态表格


前言

提示:内容大概

说明:
Dome所用到的文件有四个,可以直接复制粘贴Dome代码,路由配置组件查看效果!!!

文件说明
table.vue表格组件,封装为动态的
button.json按钮数据,模拟后端传输数据,即表格的操作列,由于每张表的操作性不一样,使用操作列的按钮也做了动态
tableData.json用户数据,无论是否动态,这个都需要
data.json表格数据,具体要几列,如何展示,都是这个文件数据控制

提示:data,json有几列配置就展示几列数据,tableData.json多出来的属性将无法展示,需要data.json配置即可


组件项目结构

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

1、tableData.json

代码如下(示例):

[
    {
        "name": "Alex",
        "age": 26,
        "email": "alex@example.com",
        "url": "https://tse4-mm.cn.bing.net/th/id/OIP-C.hcogp2ZIcyCQjIfO7qTS3QHaFO?w=283&h=200&c=7&r=0&o=5&dpr=1.3&pid=1.7"
        
    },
    {
        "name": "Olivia",
        "age": 31,
        "email": "olivia@example.com",
        "url": "https://tse4-mm.cn.bing.net/th/id/OIP-C.hcogp2ZIcyCQjIfO7qTS3QHaFO?w=283&h=200&c=7&r=0&o=5&dpr=1.3&pid=1.7"
        
    },
    {
        "name": "David",
        "age": 34,
        "email": "david@example.com",
        "url": "https://tse4-mm.cn.bing.net/th/id/OIP-C.hcogp2ZIcyCQjIfO7qTS3QHaFO?w=283&h=200&c=7&r=0&o=5&dpr=1.3&pid=1.7"
    
    },
    {
        "name": "Sophia",
        "age": 24,
        "email": "sophia@example.com",
        "url": "https://tse4-mm.cn.bing.net/th/id/OIP-C.hcogp2ZIcyCQjIfO7qTS3QHaFO?w=283&h=200&c=7&r=0&o=5&dpr=1.3&pid=1.7"
        
    }
]


2、data.json

参数说明

参数说明
key唯一值
prop数据绑定的变量名
label表格的列名
fixed是否允许此列固定,我的第一列为固定列,其他均false
type数据类型,主要用来判断是否是展示图片还是图标
width列的宽度
sortable列是否排序

代码如下(示例):

[
    {
        "key": "name",
        "prop": "name",
        "label": "姓名",
        "fixed": true,
        "type": "String",
        "width": 100,
        "sortable": false
    },
    {
        "key": "age",
        "prop": "age",
        "label": "年龄",
        "fixed": false,
        "type": "String",
        "width": 100,
        "sortable": true
    },
    {
        "key": "email",
        "prop": "email",
        "label": "邮箱",
        "fixed": false,
        "type": "String",
        "width": 200,
        "sortable": false
    },
    {
        "key": "url",
        "prop": "url",
        "label": "头像",
        "fixed": false,
        "type": "url",
        "width": 200,
        "sortable": false
    }
]

3、button.json

属性说明
id唯一值,也是判断是”编辑“还是”删除“
typeElementPlus框架的el-button的type,可以查看官网
name按钮名称

代码如下(示例):

[
    {
        "id": 1,
        "type": "primary",
        "name": "编辑"
    },
    {
        "id": 2,
        "type": "danger",
        "name": "删除"
    },
    {
        "id": 3,
        "type": "danger",
        "name": "批量删除"
    }
]

4、table.vue

说明:以下的说明情况配合着代码观看

  1. table.vue是一个封装的组件,其他组件调用即可
  2. 调用时需要对table.vue组件进行传参,但是我调试都是直接在此界面给数据,props收参的部分已经注释了
  3. 表格做了图片类型判断,并对此类型做了界面的调整
  4. 之后还有图标的,各位也可自行判断增强一下
  5. 对于编辑和删除或者其他的业务判断都需要将scops.rowitem.id的值传到父组件去判断和处理,我这里是调试优先
  6. 然后加入了一个基本的防抖,你知道的,实际业务不加防抖容易出问题很

代码如下(示例):

<template>
    <div>
        <el-table :data="tableData" v-loading="loading" stripe style="width: 100%">

            <!-- 动态生成表格列 -->
            <el-table-column v-for="column in Columns" :key="column.prop" :label="column.label" :prop="column.prop"
                :width="column.width" :fixed="column.fixed" :sortable="column.sortable" :show-overflow-tooltip="true">
                <!-- 自定义列内容 -->
                <!-- <template v-if="column.type === 'custom'">
                    <slot :name="column.prop" />
                </template> -->

                <!-- 自定义图片
                :zoom-rate="1.2" -- 缩放速度
                :preview-src-list="[scope.row.url]" -- 开启预览
                hide-on-click-modal="true" -- 随意点击取消预览
                preview-teleported="true" -- 预览置于body 之上
                -->
                <template v-if="column.type === 'url'" #default="scope">
                    <div style="display: flex; align-items: center;">
                        <el-image v-if="scope.row.url" :zoom-rate="1.2" :src="scope.row.url"
                            :preview-src-list="[scope.row.url]" fit="cover" :hide-on-click-modal="true"
                            :preview-teleported="true" style="width: 50px; height: 50px; border-radius: 50%;" />
                    </div>
                </template>
            </el-table-column>
            <!-- 固定在右侧的操作列 -->
            <el-table-column fixed="right" label="操作">
                <!-- 行级别操作按钮 -->
                <template v-if="enableRowActions" #default="scope">
                    <el-button v-for="item in buttonData" :disabled="isLoading" :type="item.type"
                        v-loading.fullscreen.lock="isLoading" @click="debouncedClick(scope.row, item.id)">{{ item.name
                        }}</el-button>
                </template>
            </el-table-column>


        </el-table>
    </div>
</template>
  
<script setup>
import { onMounted, ref } from 'vue';
import visibleColumnsss from './data.json';
import tableData from './tableData.json';
import buttonData from './button.json';
import { ElLoading } from 'element-plus';

let loading = ref(true)
let enableRowActions = ref(true)

// let tableData = ref([])

let Columns = visibleColumnsss;

onMounted(() => {
    // 1秒之后执行
    setTimeout(() => {
        loading.value = !loading.value;
    }, 1000);
})



// 接收数据
// const props = defineProps({
//     tableData: {
//         type: Array,
//         required: true
//     },
//     loading: {
//         type: Boolean,
//         default: false
//     },
//     visibleColumns: {
//         type: Array,
//         default: () => []
//     },
//     enableRowActions: {
//         type: Boolean,
//         default: false
//     }
// })

// 防抖函数
let isLoading = ref(false); // 禁用
function debounce(func, delay) {
    let timer;
    return function (...args) {
        clearTimeout(timer);
        isLoading.value = true;

        // ElementPlus 组件
        const loading = ElLoading.service({
            lock: true,
            text: 'Loading',
            background: 'rgba(0, 0, 0, 0.7)',
        })

        timer = setTimeout(() => {
            isLoading.value = false;
            loading.close();
            func.apply(this, args);
        }, delay);
    };
}
// 防抖参数
const debouncedClick = debounce(handleRow, 300);

// 根据按钮类型判断业务类型
function handleRow(row, id) {
    switch (id) {
        case 1:
            handleRowEdit(row);
            break;
        case 2:
            handleRowDelete(row);
            break;
        case 3:
            handleRowEdit(row);
            break;
        case 4:
            handleRowEdit(row);
            break;
        default:
            break;
    }
}

// 处理行编辑逻辑
function handleRowEdit(row) {
    // ...
    console.log("输出编辑的数据  ", row.name);
}
// 处理行删除逻辑
function handleRowDelete(row) {
    // ...
    console.log("输出删除的数据  ", row);
}

</script>


<style></style>
  

总结

效果

动态表格

有什么疑问的可以评论、私信,给个点赞再离开。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ItHeiMa小飞机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值