1, the background

The end of 2017, summed up the road to the front end of this year, Vue from entry to give up, and then the second palace, from Vue1.0 to Vue2.5. Combined with some actual projects of the company, it also encapsulates some more practical components.

As the company’s current management platform mainly uses Element UI, a Table component supporting page switching is encapsulated simply by combining Table and Pagination components, which is not repetitive and can be directly used in the code. (There has been a wave of optimizations over previous releases)

2. Implementation ideas

2.1 Element UI introduction (overall introduction)

main.js

// Element UI
import Element from 'element-ui'// The default style import'element-ui/lib/theme-chalk/index.css'
Copy the code

2.2 Start encapsulating iTable. Vue components (Skeleton)

Since corporate projects start with I, it is customary to name components with I to distinguish them from pages. Add the Table and Pagination components first

<template>
  <div class="table"> <! --region table --> <el-table id="iTable"></el-table> <! --endregion--> <! --> <el-pagination></el-pagination> <! --endregion--> </div> <template>Copy the code

Get into the habit of writing comments, and the amount of comments for personal projects should rarely be less than 30%

2.3. Reference the iTable component in the page and pass values to the iTable component

<template>
  <div class="table-page"> <! --region table table --> <i-table :list="list"
    :total="total" 
    :otherHeight="otherHeight" 
    :options="options"
    :pagination="pagination"
    :columns="columns" 
    :operates="operates" 
    @handleSizeChange="handleSizeChange"
    @handleIndexChange="handleIndexChange" 
    @handleSelectionChange="handleSelectionChange" 
    @handleFilter="handleFilter" 
    @handelAction="handelAction"> </i-table> <! --endregion--> </div> </template> <script> import iTable from'.. /.. /components/Table/Index'

  export default {
    components: {iTable},
    data () {
      return {
        total: 0,
        list: [],
        otherHeight: 208,
        columns: [
          {
            prop: 'id',
            label: 'number',
            align: 'center',
            width: 60
          },
          {
            prop: 'title',
            label: 'title',
            align: 'center',
            width: 400,
            formatter: (row, column, cellValue) => {
              return `<span style="white-space: nowrap; color: dodgerblue;">${row.title}</span>`
            }
          },
          {
            prop: 'state',
            label: 'state',
            align: 'center',
            width: '160',
            render: (h, params) => {
              return h('el-tag', {
                props: {type: params.row.state === 0 ? 'success' : params.row.state === 1 ? 'info' : 'danger'} // Props}, params.row.state === 0?'shelves' : params.row.state === 1 ? 'shelves' : 'Under review')
            }
          },
          {
            prop: 'author',
            label: 'the writer',
            align: 'center',
            width: 120
          },
          {
            prop: 'phone',
            label: 'Contact Information',
            align: 'center',
            width: 160
          },
          {
            prop: 'email',
            label: 'email',
            align: 'center',
            width: 240
          },
          {
            prop: 'createDate',
            label: 'Release time',
            align: 'center',
            width: 180,
            formatter: (row, column, cellValue) => {
              return this.$utils.Common.dateFormat(row.createDate, 'YYYy-mm-dd' hh: MM}}], // Need to display columns operates: {width: 200, fixed:'right',
          list: [
            {
              label: 'edit'.type: 'warning',
              show: : (index, row) => {
                retuen true
              },
              icon: 'el-icon-edit',
              plain: true,
              disabled: false,
              method: (index, row) => {
                this.handleEdit(index, row)
              }
            },
            {
              label: 'delete'.type: 'danger',
              icon: 'el-icon-delete',
              show: true,
              plain: false,
              disabled: (index, row) => {
                retuen false}, method: (index, row) => {this.handledel (index, row)}}]}, 20}, // paging parameters options: {stripe:true// Table loading:false// Whether to add table loading to load animation highlightCurrentRow:true// Whether the current line is supported to highlight mutiSelect:true// Support list item check function} // table parameters}}, components: {expandDom: {props: {column: {required:true
          },
          row: {
            required: true
          }
        },
        render (h) {
          return h('div', {}, ([this.column.render(this.row, this.column)]))
        }
     }
   },
    mounted() { }, methods: HandleSizeChange (pagination) {this.pagination = pagination}, HandleIndexChange (pagination) {this.pagination = pagination}, // Select the line handleSelectionChange (val) {console.log('val:', val)
      },
      // 编辑
      handleEdit (index, row) {
        console.log(' index:', index)
        console.log(' row:', row)}, // Delete handleDel (index, row) {console.log(' index:', index)
        console.log(' row:', row)
      }
    }
  }
</script>
Copy the code

Except for the columns and operates parameters, the other parameters should be understandable. Ok. Vue is a component of iTable. Vue is a component of iTable. Vue is a component of iTable. What’s harder to understand is the Render parameter in the columns, which uses Vue’s virtual tags in order to be able to use HTML tags and other elements of the Element UI as desired in the columns of the table. (You can also write it directly to see if the table component can recognize it.) This estimate is a difficult place for beginners to understand, detailed we can first look at the vue render, explain more clearly, if some partners do not understand, you can directly private message me ~~~

<! -- Region wrapped paging table--> <! -- Region --> <template> <div class="table">
    <el-table 
    id="iTable" 
    v-loading.iTable="options.loading" 
    :data="list" 
    :max-height="height" 
    :stripe="options.stripe"
    ref="mutipleTable"
    @selection-change="handleSelectionChange"> <! --region selection box --> <el-table-column V-if ="options.mutiSelect" type="selection" style="width: 55px;"> </el-table-column> <! --endregion--> <! --region data column --> <template v-for="(column, index) in columns">
        <el-table-column :prop="column.prop"
                         :label="column.label"
                         :align="column.align"
                         :width="column.width">
          <template slot-scope="scope">
            <template v-if=! "" column.render">
              <template v-if="column.formatter">
                <span v-html="column.formatter(scope.row, column)"></span> </template> <template v-else> <span>{{scope.row[column.prop]}}</span> </template> </template> <template v-else>  <expand-dom :column="column" :row="scope.row" :render="column.render" :index="index"></expand-dom> </template> </template> </el-table-column> </template> <! --endregion--> <! --region button operation group --> <el-table-column ref="fixedColumn" label="Operation" align="center" :width="operates.width" :fixed="operates.fixed"
                       v-if="operates.list.length > 0">
        <template slot-scope="scope">
          <div class="operate-group">
            <template v-for="(btn, key) in operates.list">
              <div class="item" v-if=! "" btn.show||&&btn.show(scope.$index,scope.row)">
                <el-button :type="btn.type" size="mini" :icon="btn.icon" :disabled="btn.disabled||&&btn.disabled(scope.$index,scope.row)"
                           :plain="btn.plain" @click.native.prevent="btn.method(key,scope.row)">{{ btn.label }} </el-button> </div> </template> </div> </template> </el-table-column> <! --endregion--> </el-table> <div style="height:12px"></div> <! -- Region pagination --> <el-pagination v-if="pagination" @size-change="handleSizeChange"
                   @current-change="handleIndexChange"
                   :page-size="tableCurrentPagination.pageSize"
                   :page-sizes="this.tableCurrentPagination.pageArray" :current-page="tableCurrentPagination.pageIndex"
                   layout="total,sizes, prev, pager, next,jumper"
                   :total="total"></el-pagination> <! --endregion--> </div> </template> <! --endregion--> <script> const _pageArray = [20, 50, 100export default {
    props: {
      list: {
        type: Array, default: [] // prop: column column, label: column name, align: left, center, right, width: column width}, // Data columns: {type: Array, default: [] // Columns to be displayed === prop: column data properties, label: column name, align: align, width: column width}, operates: {type: Object, default: {} // width: button column width, fixed: whether to fix (left,right), button set === label: text,type: type (primary/success/warning/danger/info/text), show: whether to display, icon: button icon, plain: whether to plain button, disabled: whether to disable, method: Callback method}, total: {type: Number, default: 0}, //type: Object, default: null // Page parameters === pageSize: number of pages displayed on each page, pageIndex: current page, pageArray: Display a control set of columns per page, default _page_array}, otherHeight: {type: Number, default: 160}, // Calculate the table height options: {type: Object,
        default: {
          stripe: false// Table loading:false// Whether to add table loading to load animation highlightCurrentRow:false// Whether the current line is supported to highlight mutiSelect:false}} // control parameters of the table}, components: {expandDom: {functional:true,
        props: {
          row: Object,
          render: Function,
          index: Number,
          column: {
            type: Object,
            default: null
          }
        },
        render: (h, ctx) => {
          const params = {
            row: ctx.props.row,
            index: ctx.props.index
          }
          if (ctx.props.column) params.column = ctx.props.column
          return ctx.props.render(h, params)
        }
      }
    },
    data () {
      return{pageIndex: 1, tableCurrentPagination: {}, multipleSelection: [],created () {},
    mounted () {
      if(this.pagination && ! Enclosing pagination. PageSizes) {this. Pagination. PageArray = _pageArray / / each page shows article number control} this. TableCurrentPagination = Enclosing pagination | | {pageIndex pageSize: this. Total: 1} / / determine whether need paging}, computed: {/ / calculation table heightheight () {
        return this.$utils.common.getwidthheight ().height-this.otherheight}}, methods: {handleSizeChange (size) {if (this.pagination) {
          this.tableCurrentPagination = {
            pageIndex: 1,
            pageSize: size
          }
          this.$emit('handleSizeChange', enclosing tableCurrentPagination)}}, / / switch page handleIndexChange (currnet) {if (this.pagination) {
          this.tableCurrentPagination.pageIndex = currnet
          this.$emit('handleIndexChange'}}, enclosing tableCurrentPagination), / / multi-line select handleSelectionChange (val) {enclosing multipleSelection = val this.$emit('handleSelectionChange', val)}, // Displays the filter popovershowfilterDataDialog () {
        this.$emit('handleFilter'}, // display the table operation popupshowActionTableDialog () {
        this.$emit('handelAction')
      }
    }
  }
</script>

<style lang="less" rel="stylesheet/less">
  @import ".. /.. /assets/styles/mixins";

  .table {
    height: 100%;
    .el-pagination {
      float: right;
      margin: 20px;
    }
    .el-table__header-wrapper, .el-table__fixed-header-wrapper {
      thead {
        tr {
          th {
            color: # 333333;} } } } .el-table-column--selection .cell { padding: 0; text-align: center; } .el-table__fixed-right { bottom: 0 ! important; right: 6px ! important; z-index: 1004; } .operate-group { display: flex; flex-wrap: wrap; .item { margin-top: 4px; margin-bottom: 4px; display: block; flex: 0 0 50%; } } .filter-data { top: e("calc((100% - 100px) / 3)"); Background: rgba(0, 0, 0, 0.7); } .table-action { top: e("calc((100% - 100px) / 2)"); Background: rgba(0, 0, 0, 0.7); } .fix-right { position: absolute; right: 0; height: 100px; color:#ffffff;
      width: 30px;
      display: block;
      z-index: 1005;
      writing-mode: vertical-rl;
      text-align: center;
      line-height: 28px;
      border-bottom-left-radius: 6px;
      border-top-left-radius: 6px;
      cursor: pointer;
    }
  }
</style>
Copy the code

This is all the code, forgive my limited expression ability, if you can help a little, that would be great! If the description is not detailed enough or there is a problem, ask, I will not change anyway ~~~, hahaha

The complete project or wait for me to optimize the rough! Welcome to comment