当前位置:   article > 正文

Vue2+elementUI:使用JSX和template两种方式对el-tabel+el-pagination进行封装_elementui formatter 返回jsx

elementui formatter 返回jsx

应用场景:在编写后台管理系统时,常常会用到表格和翻页器,每次都需要重复的写很麻烦,并且普通表格只需要渲染对应的prop就可以了,完全可以用一个v-for判断去解决,因此一个自带翻页器的table组件就应运而生了

实现功能:

  1. 在渲染表格时,只需要传递列表配置即可无脑渲染,无需疯狂cv然后改一些鸡毛蒜皮的小东西
  2. 根据字段判断是否自定义插槽,使用具名插槽去单独编译
  3. 分页器和翻页的方法都绑定到同一个方法,父组件接收一个渲染列表的方法即可
  4. 有JSX和template两种写法,各取所需(vue2版本)

一、tamplate写法

<template>
  <div class="hc-table">
    <el-table
        ref="filterTable"
        :row-class-name="tableRowClassName"
        v-loading="loading"
        :data="tableData"
        :cell-style="cellStyle"
        @sort-change="sortChange"
    >
      <template v-for="(item, index) in columns">
        <!-- solt 自定义列-->
        <!--
        自定义列的使用方法:
        在使用插槽时#后跟slotType
        <template #createTime="scope">
        <span>{{ parseTime(scope.row.createTime) }}</span>
        </template>
        -->
        <template v-if="item.type === 'slot'">
          <el-table-column
              :class-name="item.class"
              :key="index"
              :width="item.width"
              :prop="item.prop"
              :label="item.label"
              :align="item.align ? item.align : 'center'"
          >
            <template slot-scope="scope">
              <slot :name="item.slotType" :row="scope.row"/>
            </template>
          </el-table-column>
        </template>
        <!--普通表格-->
        <template v-else>
          <el-table-column
              :show-overflow-tooltip="item.showOverflowTooltip||true"
              v-if="item.visible !== false"
              :key="index"
              :sortable="item.sortable"
              :prop="item.prop"
              :label="item.label"
              :align="item.align ? item.align : 'center'"
              :width="item.width"
          ></el-table-column>
        </template>
      </template>
    </el-table>
    <div class="pagination-container" v-if="showPagination">
      <el-pagination
          :background="background"
          :current-page.sync="currentPage"
          :page-size.sync="pageSize"
          :layout="layout"
          :page-sizes="pageSizes"
          :pager-count="pagerCount"
          :total="total"
          v-bind="$attrs"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
      />
    </div>

  </div>
</template>

  • 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
<script>
import { scrollTo } from '@/utils/scroll-to'

export default {
  name: 'HcTable',
  props: {
    // 表单数据
    tableData: Array,
    // 数据列表配置
    columns: Array,
    // 行样式
    tableRowClassName: Function,
    // 加载状态
    loading: Boolean,
    // 单元格的 style 的回调方法
    cellStyle: Function,
    // 是否展示翻页组件
    showPagination: { type: Boolean, default: true },
    // 总数
    total: Number,
    // pagination的page
    page: Number,
    // pagination的limit
    limit: Number,
    pageSizes: {
      type: Array,
      default() {
        return [10, 20, 30, 50]
      }
    },
    // 移动端页码按钮的数量端默认值5
    pagerCount: {
      type: Number,
      default: document.body.clientWidth < 992 ? 5 : 7
    },
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },
    background: {
      type: Boolean,
      default: true
    },
    autoScroll: {
      type: Boolean,
      default: true
    },
    hidden: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    pageSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  methods: {
    sortChange(filters) {
      this.$emit('sortChange', filters)
    },
    handleSizeChange(val) {
      if (this.currentPage * val > this.total) {
        this.currentPage = 1
      }
      this.$emit('pagination', { page: this.currentPage, limit: val })
    },
    handleCurrentChange(val) {
      this.$emit('pagination', { page: val, limit: this.pageSize })
    }
  }
}
</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
<style scoped>
.pagination-container {
  background: #fff;
  padding: 32px 16px;
}

.pagination-container.hidden {
  display: none;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

二、JSX写法

<script>
export default {
  name: 'HcTable',
  props: {
    // 表单数据
    tableData: Array,
    // 数据列表配置
    columns: Array,
    // 行样式
    tableRowClassName: Function,
    // 加载状态
    loading: Boolean,
    // 单元格的 style 的回调方法
    cellStyle: Function,
    // 是否展示翻页组件
    showPagination: { type: Boolean, default: true },
    // 总数
    total: Number,
    // pagination的page
    page: Number,
    // pagination的limit
    limit: Number,
    pageSizes: {
      type: Array,
      default() {
        return [10, 20, 30, 50]
      }
    },
    // 移动端页码按钮的数量端默认值5
    pagerCount: {
      type: Number,
      default: document.body.clientWidth < 992 ? 5 : 7
    },
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper'
    },
    background: {
      type: Boolean,
      default: true
    },
    autoScroll: {
      type: Boolean,
      default: true
    },
    hidden: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    currentPage: {
      get() {
        return this.page
      },
      set(val) {
        this.$emit('update:page', val)
      }
    },
    pageSize: {
      get() {
        return this.limit
      },
      set(val) {
        this.$emit('update:limit', val)
      }
    }
  },
  methods: {
    sortChange(filters) {
      this.$emit('sortChange', filters)
    },
    handleSizeChange(val) {
      if (this.currentPage * val > this.total) {
        this.currentPage = 1
      }
      this.$emit('pagination', { page: this.currentPage, limit: val })
    },
    handleCurrentChange(val) {
      this.$emit('pagination', { page: val, limit: this.pageSize })
    },
    renderTable() {
      const { tableRowClassName, loading, tableData, cellStyle, sortChange } = this
      return <el-table
          ref="filterTable"
          row-class-name={tableRowClassName}
          v-loading={loading}
          data={tableData}
          cell-style={cellStyle}
          on-sort-change={sortChange}
      >
        {this.columns.map((item, index) =>
            this.renderTableColumn(item, index))}
      </el-table>
    },
    renderTableColumn(item, index) {
      if (item.visible === false) return
      if (item.type === 'slot') {
        /*  solt 自定义列
          自定义列的使用方法:
          在使用插槽时#后跟slotType
       */
        return <el-table-column
            class-name={item.class}
            key={index}
            width={item.width}
            prop={item.prop}
            label={item.label}
            align={item.align ? item.align : 'center'}
            formatter={(row) => {
              return this.$scopedSlots[item.slotType]({
                row: row
              })
            }}
        >
        </el-table-column>
      } else {
        // 普通表格
        return <el-table-column
            show-overflow-tooltip={item.showOverflowTooltip || true}
            key={index}
            sortable={item.sortable}
            prop={item.prop}
            label={item.label}
            align={item.align ? item.align : 'center'}
            width={item.width}
        ></el-table-column>
      }
    },
    renderPagination() {

      const {
        showPagination,
        pageSizes,
        pagerCount,
        total,
        layout,
        currentPage,
        pageSize,
        handleSizeChange,
        handleCurrentChange,
        background
      } = this
      const listeners = { // 关键代码 - 1
        'update:current-page': val => {
          this.currentPage = val
        },
        'update:limit': val => {
          this.pageSize = val
        }
      }
      if (showPagination && total > 0) {
        return <div class="pagination-container">
          <el-pagination
              background={background}
              current-page={currentPage}
              page-size={pageSize}
              layout={layout}
              page-sizes={pageSizes}
              pager-count={pagerCount}
              total={total}
              {...{ on: listeners }}
              on-size-change={handleSizeChange}
              on-current-change={handleCurrentChange}
          />
        </div>
      }
    }
  },
  render(createElement, context) {
    return <div class="hc-table">{this.renderTable()}{this.renderPagination()}</div>
  }
}
</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
  • 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
<style scoped>
.pagination-container {
  background: #fff;
  padding: 32px 16px;
}

.pagination-container.hidden {
  display: none;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三、使用方法

示例:

企业微信截图_16801673792015.png

<hc-table :loading="loading" :tableData="userList" :columns="columns" :total="total"
          :page.sync="queryParams.pageNum"
          :limit.sync="queryParams.pageSize" @pagination="getList"
>
  <template #statusStr="scope">
    {{ scope.row.status == 0 ? '正常' :'停用' }}
  </template>
  <template #operate="scope">
    <el-button
        size="mini"
        type="text"
        @click="handleUpdate(scope.row,'reset')"
    >重置密码
    </el-button>
    <el-button
        size="mini"
        type="text"
        @click="handleUpdate(scope.row,'edit')"
    >修改
    </el-button>
    <el-button
        size="mini"
        type="text"
        class="color_red"
        @click="handleDelete(scope.row)"
    >删除
    </el-button>
  </template>
</hc-table>
  • 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
// data中的columns列信息配置如下
columns: [
  { prop: 'userId', label: `序号` },
  { prop: 'userName', label: `账户名称` },
  { label: `状态`,type: 'slot',slotType:'statusStr' },
  {
    class: 'small-padding fixed-width',
    width: '160',
    label: `操作`,
    type: 'slot',
    slotType: 'operate'
  }
],
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/空白诗007/article/detail/965284
推荐阅读
相关标签
  

闽ICP备14008679号