提示: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 | 唯一值,也是判断是”编辑“还是”删除“ |
type | ElementPlus框架的el-button的type,可以查看官网 |
name | 按钮名称 |
代码如下(示例):
[
{
"id": 1,
"type": "primary",
"name": "编辑"
},
{
"id": 2,
"type": "danger",
"name": "删除"
},
{
"id": 3,
"type": "danger",
"name": "批量删除"
}
]
4、table.vue
说明:以下的说明情况配合着代码观看
- table.vue是一个封装的组件,其他组件调用即可
- 调用时需要对table.vue组件进行传参,但是我调试都是直接在此界面给数据,props收参的部分已经注释了
- 表格做了图片类型判断,并对此类型做了界面的调整
- 之后还有图标的,各位也可自行判断增强一下
- 对于编辑和删除或者其他的业务判断都需要将scops.row和item.id的值传到父组件去判断和处理,我这里是调试优先
- 然后加入了一个基本的防抖,你知道的,实际业务不加防抖容易出问题很
代码如下(示例):
<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>
总结
效果
动态表格
有什么疑问的可以评论、私信,给个点赞再离开。