【el-talbe表格封装】

el-talbe表格封装

一、组件封装

<template>
  <div class="headerTable">
    <div>
      <slot name="leftTopButton"/>
    </div>
    <div class="tableSortable">
      <el-table
        ref="table"
        v-loading="loading"
        element-loading-text="Loading"
        :data="tableData"
        :border="border"
        tooltip-effect="dark"
        style="width:100%"
        header-row-class-name="el-table_color"
        :fit="fit"
        :stripe="stripe"
        :height="height"
        :size="small"
        @row-click="rowChangeHandler"
        @selection-change="selectionChangeHandler"
      >
        <el-table-column
          type="selection"
          width="55"
        />
        <el-table-column
          v-for="(item, index) in tableLabel"
          :key="index"
          :width="item.width ? item.width : ''"
          :align="item.align"
          :label="item.label"
          :prop="item.param"
          :sortable="item.sortable ? 'custom' : false"
        >
          <template slot-scope="scope">
            <i
              v-if="index === 0"
              class="el-icon-s-operation"
            />
            <span v-if="item.render">
              {{ item.render(scope.row) }}
            </span>
            <span v-else>{{ scope.row[item.param] }}</span>
          </template>
        </el-table-column>
        <el-table-column
          v-if="tableOption.label"
          :width="tableOption.width"
          :label="tableOption.label"
        >
          <template slot-scope="scope">
            <el-button
              v-for="(item, index) in tableOption.options"
              :key="index"
              :type="item.type"
              :icon="item.icon"
              size="mini"
              @click="handleButton(item.action, scope)"
            >
              {{ item.label }}
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div>
      <slot name="pagination"/>
    </div>
  </div>
</template>

<script>
// import {parseTime} from "../utils";

import Sortable from 'sortablejs';

export default {
    name: 'TableCmp',
    props: {
    // 表格数据
        tableData: {
            type: Array,
            default: () => {
                return [];
            }
        },
        // 表格表头标题(相关的属性)
        tableLabel: {
            type: Array,
            default: () => {
                return [];
            }
        },
        // 操作按钮
        tableOption: {
            type: Object,
            default: () => {
                return {};
            }
        },
        loading: {
            type: Boolean
        },
        border: {
            type: Boolean,
            default: true
        },
        fit: {
            type: Boolean,
            default: true
        },
        stripe: {
            type: Boolean,
            default: true
        },
        height: {
            type: String,
            default: 'auto'
        },
        small: {
            type: String,
            default: 'mini'
        }
    },
    data() {
        return {
            // loadingLog: true,
            showBox: false
        };
    },
    computed: {
        loadingLog() {
            return this.loading;
        }
    },
    watch: {
        loadingLog() {
            if (this.tableData) {
                setTimeout(() => {
                    this.loadingLog = false;
                }, 1500);
            }
        }
    },
    mounted() {
        this.onDragEnd();
    },
    methods: {
        handleButton(action, scope) {
            this.$emit('handleFun', action, scope);
        },
        rowChangeHandler(row) {
            this.$emit('handleRowClick', row);
        },
        selectionChangeHandler(selected) {
            this.$emit('selectionChange', selected);
        },
        onDragEnd() {
            debugger;
            const that = this;
            // eslint-disable-next-line no-undef
            const tbody = document.querySelector('.tableSortable .el-table__body-wrapper tbody');
            Sortable.create(tbody, {
                draggable: '.tableSortable .el-table__row',
                onEnd({newIndex, oldIndex}) {
                    const currRow = that.tableData.splice(oldIndex, 1)[0];
                    that.$nextTick(() => {
                        that.tableData.splice(newIndex, 0, currRow);
                    });
                }
            });
        }
    }
};
</script>

<style scoped>
.headerTable {
  margin: 20px;
}
</style>

二、组件使用

<template>
  <div>
    <vuedraggable
      :table-data="tableData"
      :table-label="tableLabel"
      :table-option="tableOption"
      :loading="loading"
      :border="true"
      @handleFun="handleFun"
      @handleRowClick="handleRowClick"
      @selectionChange="selectionChange"
    >
      <template v-slot:leftTopButton>
        <el-button>Add Row</el-button>
      </template>
    </vuedraggable>
  </div>
</template>

<script>
import vuedraggable from '@/components/draggable/vuedraggable.vue';

export default {
    components: {
        vuedraggable
    },
    data() {
    // Generate mock table data
        const generateMockData = () => {
            const data = [];
            for (let i = 0; i < 10; i++) {
                data.push({
                    id: i + 1,
                    name: `User ${i + 1}`,
                    age: Math.floor(Math.random() * 50) + 20,
                    role: i % 2 === 0 ? 'Admin' : 'User'
                });
            }
            return data;
        };

        // Generate mock table labels
        const tableLabel = [
            {label: 'ID', param: 'id', align: 'center', sortable: true},
            {label: 'Name', param: 'name', align: 'center', sortable: false},
            {label: 'Age', param: 'age', align: 'center', sortable: true},
            {label: 'Role', param: 'role', align: 'center', sortable: false}
        ];

        // Define mock table options
        const tableOption = {
            label: 'Actions',
            width: 300,
            options: [
                {label: 'Edit', type: 'primary', icon: 'el-icon-edit', action: 'edit'},
                {label: 'Delete', type: 'danger', icon: 'el-icon-delete', action: 'delete'}
            ]
        };

        return {
            tableData: generateMockData(),
            tableLabel,
            tableOption,
            loading: false
        };
    },
    methods: {
        handleFun(action, scope) {
            switch (action) {
                case 'edit':
                    console.log('Edit row:', scope.row);
                    break;
                case 'delete':
                    console.log('Delete row:', scope.row);
                    break;
                default:
                    break;
            }
        },
        handleRowClick(row) {
            console.log('Clicked row:', row);
        },
        selectionChange(selected) {
            console.log('Selected rows:', selected);
        }
    }
};
</script>

视频预览

相关推荐
Myli_ing几秒前
考研倒计时-配色+1
前端·javascript·考研
色空大师3 分钟前
23种设计模式
java·开发语言·设计模式
余道各努力,千里自同风3 分钟前
前端 vue 如何区分开发环境
前端·javascript·vue.js
闲人一枚(学习中)3 分钟前
设计模式-创建型-建造者模式
java·设计模式·建造者模式
PandaCave10 分钟前
vue工程运行、构建、引用环境参数学习记录
javascript·vue.js·学习
软件小伟12 分钟前
Vue3+element-plus 实现中英文切换(Vue-i18n组件的使用)
前端·javascript·vue.js
2202_7544215421 分钟前
生成MPSOC以及ZYNQ的启动文件BOOT.BIN的小软件
java·linux·开发语言
蓝染-惣右介23 分钟前
【MyBatisPlus·最新教程】包含多个改造案例,常用注解、条件构造器、代码生成、静态工具、类型处理器、分页插件、自动填充字段
java·数据库·tomcat·mybatis
小林想被监督学习24 分钟前
idea怎么打开两个窗口,运行两个项目
java·ide·intellij-idea
HoneyMoose26 分钟前
IDEA 2024.3 版本更新主要功能介绍
java·ide·intellij-idea