【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>

视频预览

相关推荐
Justinc.3 分钟前
CSS3新增边框属性(五)
前端·css·css3
fruge10 分钟前
纯css制作声波扩散动画、js+css3波纹催眠动画特效、【css3动画】圆波扩散效果、雷达光波效果完整代码
javascript·css·css3
neter.asia19 分钟前
vue中如何关闭eslint检测?
前端·javascript·vue.js
~甲壳虫20 分钟前
说说webpack中常见的Plugin?解决了什么问题?
前端·webpack·node.js
代码之光_198037 分钟前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
光影少年39 分钟前
vue2与vue3的全局通信插件,如何实现自定义的插件
前端·javascript·vue.js
As977_40 分钟前
前端学习Day12 CSS盒子的定位(相对定位篇“附练习”)
前端·css·学习
susu108301891142 分钟前
vue3 css的样式如果background没有,如何覆盖有background的样式
前端·css
ajsbxi43 分钟前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
Ocean☾43 分钟前
前端基础-html-注册界面
前端·算法·html