使用element-ui封装一个可编辑表格(扩展性极大)

使用element-ui封住一个可编辑表格

使用element-ui封装的,初学者适用,大神勿喷。。。直接上代码!!!!!!

先给你来个图片 样式可以自己调整,
使用element-ui封装一个可编辑表格(扩展性极大)_第1张图片

使用方法(举例并加上注解):

<!-- 
使用方法:
1.引入组件,
2. 组件写法:(注意,数据中的操作使用插槽弄进去的,不用也不用写这个==>  <template slot-scope="scope" slot="btn">......)
        注意点:需要用什么方法对表格进行操作,自己写  细节我就不写了 
     <EditTable :setting="setting"
                       :selectionChange="selectionChange"
                       :editPropData="editPropData">
                <template slot-scope="scope"
                          slot="btn">
                    <el-button icon="el-icon-edit-outline"
                               type="text"
                               style="color:#00B998"
                               @click="edit(1,scope.row)">编辑</el-button>
                    <el-button type="text"
                               style="color:#FF5F55"
                               @click="del(2,scope.row)"
                               icon="el-icon-delete">删除</el-button>
                </template>
    </EditTable>


3.data中的数据
setting: {
     //***************************边框,可拉长,建议使用***************************
                border: true,
     //***************是否使用index(序号)和selection(复选框),table的id***************************
                header: {
                    index: true,
                    selection: true,
                    id: "sample-input-edit-table",
                },
     // **********************是否使用page分页****************************
                page: { total: 15 },
    //**************************1.type(必选,不需要编辑的使用text,下拉框使用select,时间使用date,使用操作使用btn)
                                2.filter:(字面意思,过滤,可选)可以写一个**方法(methods)**,效果不错,
                                3.fixed:(可选)定位
                                4.=========后面自己加,一些小的细节自己弄!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                setting: [
                    { name: "条码号", prop: "barcode", width: 200, type: "text" },
                    { name: "送检单位", prop: "inspectionUnit", type: "select", width: 250, options: [], filter: this.inspectionUnit_name },
                    { name: "采样时间", prop: "samplingTime", type: "date", width: 250, filter: this.formatDate },
                    { name: "病人姓名", prop: "patientName", type: "input" },
                    {
                        name: "性别",
                        prop: "gender",
                        type: "select",
                        filter: this.genderS,
                        options: [
                            { label: "男", value: 1 },
                            { label: "女", value: 0 },
                        ],
                    },
                    { name: "年龄", prop: "year", type: "input" },
                    { name: "科室", prop: "department", type: "input" },
                    { name: "医生", prop: "sendDoctor", type: "input" },
                    { name: "门诊/住院号", prop: "opc", type: "input" },
                    { name: "床号", prop: "bedNumber", type: "input" },
                    { name: "临床诊断", prop: "clinicalDiagnosis", type: "input", width: 250 },
                    { name: "检测套餐", prop: "packageNameList", width: 250, type: "select", options: [] },
                    { name: "操作", width: 250, type: "btn", fixed: "right" },
                ],
                // 存放数据的地方
                data: [{ reason: 1111, merry: "212112" }],
            },     
4.给你一些附带的方法(methods)
          inspectionUnit_name(val) {
         
          },
        formatDate(datePram) {
            if (datePram) {
                var date = new Date(datePram);
                var YY = date.getFullYear() + "-";
                var MM = (date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1) + "-";
                var DD = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
                var hh = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
                var mm = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
                var ss = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
                return YY + MM + DD + " " + hh + mm + ss;
            } else {
                return "";
            }
        },
        del(){

        },
        edit(){

        },
        // 选择table行数据
        selectionChange(val) {
            this.selection = val;
        },
        // 修改数据成功后=====
        editPropData(row, prop) {
            let params = {};
            params.id = row.id;
            下面自己项目中贴合实际弄!!!!!!!!!!!!!!!!!!!!!!!!!!!!!这个方法是编辑数据后的  很重要 必要的
            // if (prop === "packageNameList") {
            //     params.detectionPackageVoList = [{ id: row[prop] }];
            // } else {
            //     params[prop] = row[prop];
            // }
            // http("post", this.urlList.update, params).then((res) => {
            //     const { code, data } = res;
            //     if (code == 200) {
            //         this.search();
            //         Message.success("修改成功!");
            //     }
            // });
        },


-->

代码片

<template>
    <div>
        <el-table :data="setting.data"
                  ref="table"
                  :id="setting.header.id||'edit-table'"
                  class="table_height_set"
                  :row-class-name="tableRowClassName"
                  style="width: 100%"
                  :height="height"
                  stripe
                  :border="setting.border"
                  tooltip-effect="dark"
                  @selection-change="handleSelectionChange"
                  @sort-change="sortChange"
                  :header-cell-style="{background:'#ebf7ff',color:'#30343F','font-size':'14px'}"
                  :cell-style="{color:'#30343F','font-size':'14px',height:'40px','line-height': '40px'}"
                  :row-style="{height:'40px','line-height': '40px'}"
                  @cell-click="tabClick">
            <el-table-column type="selection"
                             align='center'
                             v-if="setting.header.selection"
                             fixed="left"
                             width="55">
            </el-table-column>
            <el-table-column width="55"
                             type="index"
                             v-if="setting.header.index"
                             align="center"
                             fixed="left"
                             label="序号">
            </el-table-column>
            <el-table-column v-for=" item in setting.setting"
                             :key="item.prop"
                             :prop="item.prop"
                             :fixed="item.fixed"
                             :label="item.name"
                             :width="item.width|| '130'"
                             align="center">
                <template slot-scope="scope">
                    <div v-if="scope.row.index === tabClickIndex && tabClickLabel === item.name">
                        <div v-if="item.type=='input'"
                             class="propsItem">
                            <div class="item0 el-icon-close"
                                 @click="blurCancel(scope.row,item.prop)"></div>
                            <el-input v-model="scope.row[item.prop]"
                                      maxlength="300"
                                      placeholder="请输入"
                                      class="item1"
                                      size="mini" />
                            <div class="item2 el-icon-check"
                                 @click="inputBlur(scope.row,item.prop)"></div>
                        </div>

                        <div v-if="item.type==='select'"
                             class="propsItem">
                            <div class="item0 el-icon-close"
                                 @click="blurCancel(scope.row,item.prop)"></div>
                            <el-select v-model="scope.row[item.prop]"
                                       class="item1"
                                       placeholder="请选择">
                                <el-option v-for="item in item.options||[]"
                                           :key="item.value"
                                           :label="item.label"
                                           :value="item.value">
                                </el-option>
                            </el-select>
                            <div class="item2 el-icon-check"
                                 @click="inputBlur(scope.row,item.prop)"></div>
                        </div>

                        <div v-if="item.type==='date'"
                             class="propsItem">
                            <div class="item0 el-icon-close"
                                 @click="blurCancel(scope.row,item.prop)"></div>
                            <el-date-picker v-model="scope.row[item.prop]"
                                            class="item1"
                                            type="datetime"
                                            format="yyyy-MM-dd HH:mm:ss"
                                            value-format="timestamp"
                                            placeholder="选择日期时间">
                            </el-date-picker>

                            <!--  format="yyyy-MM-dd HH:mm:ss" -->
                            <div class="item2 el-icon-check"
                                 @click="inputBlur(scope.row,item.prop)"></div>
                        </div>
                        <div v-if="item.type==='text'"
                             class="propsItem">
                            {{scope.row[item.prop]}}
                        </div>
                    </div>
                    <!-- v-if="tabClickIndex===null&& tabClickLabel === ''" -->
                    <span v-else>{{ item.filter?item.filter(scope.row[item.prop]):scope.row[item.prop]}}</span>
                    <slot name="btn"
                          v-if="item.type == 'btn'"
                          :row="scope.row">
                    </slot>
                </template>
            </el-table-column>

            <!-- <el-table-column label="操作"
                             fixed="right"
                             width="250"
                              v-if="setting.slot.btn"
                             align="center"
                            >
                <template slot-scope="scope">
                   
                </template>
            </el-table-column> -->

        </el-table>
        <!-- 分页 -->
        <div class="page-box"
             v-if="setting.data.length != 0 && setting.page &&setting.page.total">
            <el-pagination background
                           @size-change="handleSizeChange"
                           @current-change="handleCurrentChange"
                           :current-page="page.pageNumber"
                           :page-sizes="[10, 20, 30, 50]"
                           :page-size="page.pageSize"
                           layout="total, sizes, prev, pager, next, jumper"
                           :total="setting.page.total">
            </el-pagination>
        </div>
    </div>
</template>

<script>
export default {
    data() {
        return {
            tabClickIndex: null, // 点击的单元格
            tabClickLabel: "", // 当前点击的列名
            defaltPropData: "", //修改时默认数据
            page: {
                pageSize: 10,
                pageNumber: 1,
            },
        };
    },
    props: {
        setting: {
            type: Object,
            require: true,
        },
        selectionChange: {
            type: Function,
            default: () => {},
        },
        editPropData: {
            type: Function,
            default: () => {},
        },
        sortChange: {
            type: Function,
            default: () => {},
        },
        rowClassName: {
            type: Function,
            default: () => {},
        },
        height: {
            type: String,
            default: "500",
        },
        pageChange: {
            type: Function,
            default: () => {},
        },
    },
    methods: {
        // ===========================================table方法==================================
        tableRowClassName({ row, rowIndex }) {
            // 把每一行的索引放进row
            row.index = rowIndex;
            // name名字
            this.rowClassName({ row, rowIndex });
            // 例子:如:
            //   if (row.samplePackageId && row.receivePackageId !== row.samplePackageId) {
            //     return "sample-confirm-err-row";
            // }
        },
        //  row 当前行 column 当前列
        tabClick(row, column, cell, event) {
            this.defaltPropData = row[column.property];
            if (this.tabClickIndex !== null || column.type !== "default" || column.label === "操作") {
                return;
            }
            // 如果其属性是text,则不能点击
            let data = this.setting.setting.filter((item) => {
                return item.prop === column.property;
            });
            if (data[0].type === "text") {
                return;
            }
            this.tabClickIndex = row.index;
            this.tabClickLabel = column.label;
        },
        blurCancel(row, prop) {
            row[prop] = this.defaltPropData;
            this.tabClickIndex = null;
            this.tabClickLabel = "";
        },

        // 修改后
        inputBlur(row, prop) {
            // let params = {};
            this.editPropData(row, prop);
            this.tabClickIndex = null;
            this.tabClickLabel = "";
        },
        //多选
        handleSelectionChange(val) {
            let len = val.length;
            let arr = [];
            for (var i = 0; i < len; i++) {
                arr.push(val[i]["id"]);
            }
            this.selectionChange(arr);
        },
        // ****************************************************===============================================
        // ************************分页组件方法*****************================================================
        handleSizeChange(val) {
            // pagesize
            console.log(`每页 ${val}`);
            this.page.pageSize = val;
            this.page.pageNumber = 1;
            // page组件发生改变后出发父组件的方法,并且把page的参数传递过去
            this.pageChange(this.page);
            this.$forceUpdate();
        },
        handleCurrentChange(val) {
            this.$forceUpdate();
            this.page.pageNumber = val;
            this.pageChange({
                pageSize: this.page.pageSize,
                pageNumber: this.page.pageNumber,
            });
        },
    },
    watch: {
        "page.pageNumber": {
            handler(newVal) {
                this.page.pageNumber = newVal;
            },
            deep: true,
        },
        "setting.data": {
            handler(newVal) {
                if (newVal.length == 0 && this.page.pageNumber != 1) {
                    this.page.pageNumber = Number(this.page.pageNumber) - 1;
                    this.pageChange(this.page);
                }
            },
            deep: true,
        },
    },
};
</script>


<style lang="less" scoped>
.table_height_set {
    .propsItem {
        display: flex;
        justify-content: center;
        align-items: center;
        .item0 {
            margin-right: 10px;
            width: 15px;
            height: 15px;
            border: 1px solid #ccc;
            font-size: 14px;
            font-weight: 600;
            color: red;
        }
        .item1 {
            width: 220px;
        }
        .item2 {
            margin-left: 10px;
            width: 15px;
            height: 15px;
            border: 1px solid #ccc;
            font-size: 14px;
            font-weight: 600;
            color: green;
        }
    }
}
.page-box {
    margin: 20px 0;
    text-align: right;
}
</style>

你可能感兴趣的:(ui,javascript,elementui)