当前位置:   article > 正文

el-table 两种方法封装_el-table 封装

el-table 封装


main.js引入全局组件
问题:el-table-column只能放在el-table标签中,(多级表头时)单独封装会使表格列错位
解决:复杂表头需要加一列防止列错位,设置width为-1

一、第一种

1. 组件

<template>
  <div>
    <el-table :size="elTableSize" :data="tableData" :stripe="false" :border="columObj.border" :show-header="true" :highlight-current-row="true" @selection-change="handleSelectionChange" v-loading="columObj.loading" :row-class-name="tableRowClassName" @row-click="rowClick" :header-cell-style="$headerCellStyleFun" :cell-style="$cellStyleFun">
      <!-- 选择框是否开启,selectable控制是否单行禁用 -->
      <el-table-column v-if="columObj.selection" fixed type="selection" :selectable="columObj.selectable" width="50" />
      <!-- 序号列是否开启 -->
      <el-table-column v-if="columObj.showIndex" fixed type="index" label="序号" width="54" class-name="order_column" />
      <!-- 普通列 -->
      <!-- <el-table-column v-for="(column,columIndex) in columObj.columnData" :key="columIndex" :prop="column.prop" :label="column.label" :fixed="column.fixed" :width="column.width?column.width:column.multiLine?'300px':''" :sortable="column.sortable" :index="columIndex" :render-header="$renderHeaderFun"> -->
      <el-table-column v-for="(column,columIndex) in columObj.columnData" :key="columIndex" :prop="column.prop" :label="column.label" :fixed="column.fixed" :width="column.width?column.width:column.multiLine?'300px':''" :sortable="column.sortable" :index="columIndex">
        <template slot="header" slot-scope="scope">
          <div class="table-head">{{ $rewriteHeader(scope) }}</div>
        </template>
        <template slot-scope="{row,$index}">

          <!-- 默认展示 -->
          <span v-if="column.text && column.editRow != $index">
            <el-tooltip v-if="column.multiLine" :content="row[column.prop]" placement="top">
              <p class="descStyle">{{row[column.prop]}}</p>
            </el-tooltip>
            <span v-else>{{row[column.prop]}}</span>
          </span>

          <!-- 自定义内容 -->
          <span v-if="column.ownDefined">{{column.ownDefinedReturn(row,$index)}}</span>

          <!-- tag -->
          <div v-if="column.isTag">
            <el-tag :size="elTableBtnSize" :type="column.getType(row,$index)">{{column.ownDefinedReturn(row,$index)}}</el-tag>
          </div>

          <!-- 状态对象展示 -->
          <span v-if="column.status && row[column.prop]">{{row[column.prop].msg}}</span>

          <!-- switch开关 -->
          <el-switch v-if="column.switch" v-model="row[column.prop]" :inactive-text="row[column.prop] ? column.openText:column.closeText" @change="switchChange(row,$index,column.prop)" />

          <!-- 图片展示 -->
          <el-popover trigger="hover" placement="top" popper-class="popper">
            <img v-if="column.image" :src=" row[column.prop]" />
            <el-image slot="reference" v-if="column.image" :src="row[column.prop]" />
          </el-popover>

          <!-- 图片数组 -->
          <el-popover v-if="column.imageArr" trigger="hover" placement="top" popper-class="popper">
            <img v-if="row[column.prop].length>0" :src="row[column.prop][0]" />
            <el-image slot="reference" v-if="row[column.prop].length >0" :src="row[column.prop][0]" :preview-src-list="row[column.prop]" />
          </el-popover>

          <!-- 可编辑input,仅在text默认展示类型才可编辑-->
          <el-input v-focus v-if="column.editRow == $index" v-model="row[column.prop]" @blur="editInputBlur(row,$index,column.prop,columIndex)" />

          <!-- 操作按钮 -->
          <div v-if="column.isOperation">
            <span v-for="(operations, index) in column.operation" :key="index">
              <!-- <Buttons :size="elTableBtnSize" :type="operations.type" @parentClick="operations.buttonClick(row,$index)">
                <span slot="title">{{operations.label}}</span>
              </Buttons> -->
              <el-button v-if="operations.isShow(row,$index)" :size="elTableBtnSize" :type="operations.type" @click="operations.buttonClick(row,$index)" :icon="operations.icon">{{operations.label}}</el-button>
            </span>
          </div>

        </template>
      </el-table-column>
      <!-- 操作列 -->
      <!-- <el-table-column v-for="(column,columIndex) in columObj.OperationList" :key="'c'+columIndex" :prop="column.prop" :label="column.label" :width="actionColWidth" class-name="operate-button" fixed="right" :sortable="column.sortable" :index="columIndex"> -->
      <el-table-column v-for="(column,columIndex) in columObj.OperationList" :key="'c'+columIndex" :prop="column.prop" :label="column.label" :width="column.width" class-name="operate-button" fixed="right" :sortable="column.sortable" :index="columIndex">
        <template slot="header" slot-scope="{column}">
          <div class="table-head">{{ $rewriteOperateHeader(column) }}</div>
        </template>
        <template slot-scope="{row,$index}">
          <!-- 操作按钮 -->
          <span v-for="(operations, index) in column.operation" :key="index">
            <!-- <Buttons :size="elTableBtnSize" :type="operations.type" @parentClick="operations.buttonClick(row,$index)">
                <span slot="title">{{operations.label}}</span>
              </Buttons> -->
            <el-button v-if="operations.isShow(row,$index)" :size="elTableBtnSize" :type="operations.type" @click="operations.buttonClick(row,$index)" :icon="operations.icon">{{operations.label}}</el-button>
          </span>
        </template>
      </el-table-column>

    </el-table>
    <!-- 分页 -->
    <!-- <div class="page_div" :style="{textAlign: pageObj.position || 'center'}">
      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :hide-on-single-page="false" :current-page="pageObj.pageData.page" :pager-count="7" :page-sizes="[10, 15, 20, 30,50]" :page-size="pageObj.pageData.size" background layout="total,sizes,prev, pager, next" :total="pageObj.total">
      </el-pagination>
    </div> -->
  </div>
</template>
 
<script>
export default {
  name: "index",
  directives: {
    // 自定义指令,用于可编辑input自动获取焦点
    focus: {
      inserted: function (e) {
        e.querySelector('input').focus()
      }
    }
  },
  props: {
    tableData: {
      type: Array,
      required: true
    },
    columObj: {
      type: Object,
      required: true
    },
    //columObj.type(如果为""空,就不会加载多选框,或者index编号),lazy(是否支持懒加载)
    //columnData.columType(列类型,可选text(默认为普通文字模式),input(input可编辑框),switch(switch开关),image(图片),operation(操作按钮))
    //prop(参数),label(列名),width(宽度),align(对齐方式),sortable(是否支持排序)
    //如果为操作列,则需要填写需要的操作按钮,类型为Object。type(按钮样式,参考el—botton类型),label(按钮文字)icon(参考el-icon),color(字体颜色),buttonClick为点击后调用的方法名称
    // pageObj: {
    //   type: Object,
    //   required: true
    // }
  },
  data() {
    // let readUploadFileUrl = this.$store.state.user.readUploadFileUrl;
    return {
      selectVal: []
      // viewUrl: readUploadFileUrl,
    }
  },
  mounted() {
    this.$nextTick(() => {
      // this.getTableColumnWidth()
    })
  },
  methods: {
    // 复选框选中的数据
    handleSelectionChange(val) {
      this.selectVal = val
    },
    // switchChange调用
    switchChange(row, $index, prop) {
      this.$emit("switchChange", row, $index, prop);
    },
    // 帮助点击行,获取点击的下标
    tableRowClassName({
      row,
      rowIndex
    }) {
      row.rowIndex = rowIndex;
    },
    // 点击行
    rowClick(row, column, event) {
      this.$emit("rowClick", row, column, event);
    },
    // 可编辑input失去焦点
    editInputBlur(row, $index, prop, columIndex) {
      this.$emit('editInputBlur', row, $index, prop, columIndex);
    },
    // 条数变化
    handleSizeChange(e) {
      this.$emit('handleSizeChange', e);
    },
    // 页码变化
    handleCurrentChange(e) {
      this.$emit('handleCurrentChange', e);
    }
  },
  computed: {},
}
</script>

<style lang="scss" scoped>
.el-button {
  margin: 0 6px;
}
::v-deep .el-input__inner {
  border: none;
}
::v-deep .el-image__inner {
  height: 50px;
}
// switch左边文字颜色
::v-deep .el-switch__label--left {
  color: #606266;
}
img {
  height: 400px;
}
.page_div {
  padding: 15px 0;
}
</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
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189

2. 调用

<elTables ref="elTables" :tableData="tableList" :columObj="columObj"> </elTables>
  • 1
data() {
  return {
    // 表格
    tableList: [],
    columObj: {
      border: true,
      loading: false,
      // 选择框
      selection: true,
      // 序号列
      showIndex: true,
      // 选择框根据条件是否可选
      selectable: (row, index) => {
        if (row.switchs) {
          return true;
        }
      },
      lazy: "true",
      //column列,columType(列类型,可选text(默认为普通文字模式),input(input可编辑框),switch(switch开关),image(图片),operation(操作按钮))
      //prop(参数),label(列名),width(宽度),align(对齐方式),sortable(是否支持排序)
      columnData: [
        {
          text: true,
          prop: "name",
          label: "姓名",
          width: "100px",
          fixed: true,
        },
        {
          ownDefined: true,
          prop: "sex",
          label: "性别",
          width: "80px",
          ownDefinedReturn: (row, $index) => {
            return this.getResult(row.sex, this.dataJSON.sex, $index)
          }
        },
      ],
      // 操作列
      //如果为操作列,则需要填写需要的操作按钮,类型为Object。operation(操作类型,可选edit,delete,see),type(按钮样式,参考el—botton类型),label(按钮文字)icon(参考el-icon),color(字体颜色)
      isOperation: true,
      OperationList: [
        {
          label: "操作",
          width: "280",
          fixed: "right",
          align: "center",
          sortable: false,
          operation: [
            {
              type: "primary",
              label: "编辑",
              buttonClick: this.showEditPopup, // 点击编辑按钮
              isShow: (row, $index) => {
                return true;
              }
            },
          ]
        },
      ]
    },
  }
},
// 根据返回数据匹配字典数据
getResult(rowVal, zidian, $index) {
  let result
  zidian.forEach(item => {
    if (rowVal !== "" && item.value == rowVal) {
      result = item.name
    }
  });
  return result
},
  • 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

二、第二种 - 使用插槽

1. 组件

cusTable.vue

<template>
  <div class="el-table">
    <el-table class="my-table" ref="table" :data="listData" border style="width: 100%" @selection-change="handleSelectionChange">
      <!-- 是否需要选择器 -->
      <el-table-column fixed v-if="showSelectColumn" type="selection" align="center" width="60"></el-table-column>
      <!-- 是否需要序号 -->
      <el-table-column fixed v-if="showIndexColumn" type="index" align="center" width="60"></el-table-column>
      <!-- <template> -->
      <!-- <elCol :propList="propList"></elCol> -->
      <el-table-column v-for="propItem in propList" :key="propItem.prop" v-bind="propItem" align="center">
      	<!-- 复杂表头时使用elCol组件 -->
        <template v-if="propItem.fzCol">
          <!-- 多级表头时使用elCol组件 -->
          <elCol :propList="propItem.colList"></elCol>
          <!-- 二级表头可以使用一下代码 -->
          <!-- <el-table-column v-for="item in propItem.colList" :key="item.prop" v-bind="item" align="center">
            <template #default="scope">
              <slot :name="item.slotName" :row="scope.row">
                {{ scope.row[item.prop] }}
              </slot>
            </template>
          </el-table-column> -->
        </template>
        <!-- 一行表头,简单表格 -->
        <template v-if="!propItem.fzCol" #default="scope">
          <!-- 为表格预留插槽 -->
          <slot :name="propItem.slotName" :row="scope.row">
            {{ scope.row[propItem.prop] }}
          </slot>
        </template>
      </el-table-column>
      <!-- </template> -->
    </el-table>
  </div>
</template>
  
<script>
export default {
  name: "cus-table",
  props: {
    listData: {
      type: Array,
      required: true
    },
    propList: {
      type: Array,
      required: true
    },
    showSelectColumn: {
      type: Boolean,
      required: false
    },
    showIndexColumn: {
      type: Boolean,
      required: false
    },
  },
  data() {
    return {};
  },
  mounted() {
    this.$nextTick(() => {
      this.$refs.table.doLayout()
    })
  },
  methods: {
    handleSelectionChange(value) {
      this.$emit('selectionChange', value)
    }
  },
};
</script>
  • 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

elCol.vue

<template>
  <!-- 复杂表头 -->
  <div>
  	<!-- 复杂表头加一列防止列错位,设置width为-1 -->
    <el-table-column class="my-column" width="-1" ></el-table-column>
    <el-table-column v-for="(propItem,index) in propList" :key="index" v-bind="propItem" align="center">
      <template v-if="propItem.fzCol">
      	<!-- 调用本身(elCol组件) -->
        <elCol :propList="propItem.colList"></elCol>
      </template>
      <template v-if="!propItem.fzCol" #default="scope">
        <slot :name="propItem.slotName" :row="scope.row" :index="scope.$index">
          {{ scope.row[propItem.prop] }}
        </slot>
      </template>
    </el-table-column>
  </div>
</template>
  
<script>
export default {
  name: "elCol",
  props: {
    propList: {
      type: Array,
      required: true
    },
  },
};
</script>
  • 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

2. 调用

<template>
  <div class="content">
    <cusTable :listData="userList" :propList="propList" :showSelectColumn="true" :showIndexColumn="true" @selectionChange="selectionChange">
      <!-- 传入插槽,插槽支持多个 -->
      <!-- 第一种 -->
      <template #sex="{ row }">
        <span>{{ row.sex === '1' ? '男' : '女' }}</span>
      </template>
      <template #status="scope">
        <el-button type="text">{{ scope.row.status === '1' ? '是' : '否' }}</el-button>
      </template>
      <!-- 第二种 -->
      <template slot="sex" slot-scope="{ row }">
        <span>{{ row.sex === '1' ? '男' : '女' }}</span>
      </template>
      <template slot="status" slot-scope="scope">
        <span>{{ scope.row.status === '1' ? '是' : '否' }}</span>
      </template>
      <template #handler>
        <div class="handle-btns">
          <el-button icon="el-icon-edit" size="mini" type="text">编辑</el-button>
          <el-button icon="el-icon-delete" size="mini" type="text">删除</el-button>
        </div>
      </template>
    </cusTable>
  </div>
</template>

<script>
import cusTable from '../unit/table.vue'
export default {
  name: "index2",
  components: {
    cusTable
  },
  data() {
    return {
      userList: [],
      propList: [
        { prop: 'name', label: '用户名', width: '100' },
        { prop: 'cellphone', label: '手机号码', minWidth: '100' },
        // slotName 需要自定义数据的插槽名
        { prop: 'sex', label: '性别', minWidth: '100', slotName: 'sex' },
        { prop: 'status', label: '是否', minWidth: '100', slotName: 'status' },
        // fzCol 复杂表头
        {
          label: '地址',
          minWidth: '250',
          fzCol: true,
          colList: [
            {
               label: '市/区', minWidth: '100',
              fzCol: true,
              colList: [
                { prop: 'city', label: '市', minWidth: '100' },
                { prop: 'qu', label: '区', minWidth: '100' },
              ]
            },
            { prop: 'cun', label: '村', minWidth: '100' },
          ]
        },
        {
          prop: 'createAt',
          label: '创建时间',
          minWidth: '250',
        },
        { label: '操作', minWidth: '120', slotName: 'handler' }
      ]
    };
  },
  created() {
    // 异步操作后给表格赋值
    this.userList = [
      {
        name: '张三',
        cellphone: '188888888888',
        sex: '1',
        status: '1',
        createAt: '2023-4-17',
        city: 'A市',
        qu: 'A区',
        cun: 'A村',
      },
      {
        name: '李四',
        cellphone: '188888888888',
        sex: '1',
        status: '0',
        createAt: '2023-4-17',
        city: 'B市',
        qu: 'B区',
        cun: 'B村',
      }
    ]
  },
  mounted() { },
  methods: {
    selectionChange(val) {
      console.log(val)
    }
  },
};
</script>
  • 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

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