当前位置:   article > 正文

Vue+ElementPlus实现动态表格_vue动态创建表格

vue动态创建表格

提示: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"
        
    }
]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

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
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

3、button.json

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

代码如下(示例):

[
    {
        "id": 1,
        "type": "primary",
        "name": "编辑"
    },
    {
        "id": 2,
        "type": "danger",
        "name": "删除"
    },
    {
        "id": 3,
        "type": "danger",
        "name": "批量删除"
    }
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

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>
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145

总结

效果

动态表格

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/91635?site
推荐阅读
相关标签
  

闽ICP备14008679号