领导说你这个element的table过于枯燥乏味,已经知足不了我了,给我加几个功能吧

拖拽打印等功能javascript

功能概述

  • 我要表头能拖拽排序
  • 我要表头能自定义显示隐藏
  • 我要调整好表格能打印
  • 每一项我均可能要加排序,是后台排序

你安排我我就作呗

效果展现

思路分析

拖拽

拖拽大概有两种(onmousemove,ondrag),简单的具体思路都是,记录下开始点,再获取到结束点,交换完事css

表头自定义

在表头右边加个自定义下拉按钮html

打印

打印浏览器不是有么,调用print()就能够,打印表格估计就是把表格这块抠出来,弄到个新文档,打印vue

排序

是后台排序,那我就只要监听个事件回调,调后台就能够了java

参考

因为老衲过于菜鸡,保守起见,仍是先来查查别人是怎么弄的吧git

参考(fuzhi)地址github

拖拽chrome

打印浏览器

实现

打印
  • 扣出须要打印的区域innerHTML到新建的一个iframe页面里面
  • 获取到样式怼进去
  • print()打印
<template>
    <div>
        <div ref="template">
            <slot>
            </slot>
        </div>
        <button v-if="buttonShow" @click="print" type="button" :class="buttonClass">
            <span>开始打印</span>
        </button>
    </div>
</template>
复制代码
export default {
  props: {
    // 是否显示默认的打印按钮
    buttonShow: {
      type: Boolean,
      default: false
    },
    buttonClass: {
      type: String,
      default: 'el-button el-button--default'
    }
  },
  mounted () {
    this.init()
  },
  methods: {
    init () {
      let printI = document.getElementById('easyPrintIframe')
      if (!printI) {
        printI = document.createElement('iframe')
        printI.id = 'easyPrintIframe'
        printI.style.position = 'fixed'
        printI.style.width = '0'
        printI.style.height = '0'
        printI.style.top = '-100px'
        // 兼容ie
        if (
          window.location.hostname !== document.domain && navigator.userAgent.match(/msie/i)
        ) {
          printI.src = 'javascript:document.write("<head><script>document.domain="' + document.domain + '";</s' + 'cript></head><body></body>")'
        }
        printI.onload = () => {
          this.getStyle()
        }
        document.body.appendChild(printI)
      } else {
        this.getStyle()
      }
    },
    print () {
      if (typeof this.beforeCopy === 'function') {
        // 检测到有复制前须要执行的功能
        this.beforeCopy()
      }
      let $iframe = document.getElementById('easyPrintIframe')
      // 复制body,打印内容
      $iframe.contentDocument.body.innerHTML = this.$refs.template.innerHTML
      if (typeof this.beforePrint === 'function') {
        // 检测到有打印前须要执行的功能
        // 好比有些二维码组件没法直接复制dom完成。
        this.beforePrint()
      }
      setTimeout(() => {
        $iframe.contentWindow.print()
      }, 100)
    },
    getStyle () {
      let mystyle = ``
      let printI = document.getElementById('easyPrintIframe')
      var str = ''
      var styles1 = document.querySelectorAll('style')
      for (var i = 0; i < styles1.length; i++) {
        str += styles1[i].outerHTML
      }
      // console.log(str)
      printI.contentDocument.head.innerHTML = str + mystyle
      // 添加link引入
      let styles = document.querySelectorAll('link')
      for (let i = 0; i < styles.length; i++) {
        // chrome 正常,firefox不正常,能执行到,可是添加没结果
        let link = document.createElement('link')
        link.setAttribute('rel', 'stylesheet')
        if (styles[i].type) link.setAttribute('type', styles[i].type)
        else link.setAttribute('type', 'text/css')
        link.setAttribute('href', styles[i].href)
        link.setAttribute('media', 'all')
        printI.contentDocument.head.appendChild(link)
      }
    }
  }
}

复制代码
表头操做拖拽排序
  • 表头元素都添加handleMouseMove事件,移动过程当中,移到别的列上,交换位置
<template>
  <div>
    <div class="w-table" :class="{'w-table_moving': dragState.dragging}">
        <div class="edit">
            <el-dropdown type="primary" size="small" trigger="click">
              <span class="el-dropdown-link">
                <i class="el-icon-edit"></i>
              </span>
              <el-dropdown-menu slot="dropdown">
                <el-dropdown-item v-for="(item, index) in tableHeaderBackup" :key="index">
                  <div>
                    <el-checkbox v-model="item.show" @change="init">{{item.label}}</el-checkbox>
                  </div>
                </el-dropdown-item>
                <el-dropdown-item style="padding:10px 15px 8px;">
                  <el-button @click="print" type="primary" style="width:100%;" icon="el-icon-download" size="small">打印</el-button>
                </el-dropdown-item>
              </el-dropdown-menu>
            </el-dropdown>
        </div>
      
        <easy-print ref="print">
        <el-table ref="table" row-key="id" :data="tableData" :header-cell-class-name="headerCellClassName" :cell-class-name="cellClassName" :style="`width: 100%`" >

          <template v-for="(col, index) in tableHeaderYes ">
            <el-table-column v-if="col.show" :key="index" :prop="col.prop" :label="col.label" :width="col.width" :min-width="col.minWidth" :type="col.type" :header-align="col.headerAlign" :column-key="index.toString()" :render-header="renderHeader" >
            <template slot-scope="scope" >
              <div v-if="col.format" v-html="col.format(scope.row[col.prop])"></div>
              <div v-else>{{scope.row[col.prop]}}</div>
            </template>
            </el-table-column>
          </template>
        </el-table>
        </easy-print>
    </div>
  </div>
</template>
复制代码
export default {
    data () {
        return {
          dragState: {
            start: -9, // 起始元素的 index
            end: -9, // 移动鼠标时所覆盖的元素 index
            dragging: false, // 是否正在拖动
          },
          tableHeaderBackup: [], //备份完整的tableHeader
          tableHeaderYes: [],// 须要在表头显示的
          tableHeaderNo: [], // 暂时不显示的
          tableHeader: [
            {
                prop: 'name',
                label: '油站名称',
                show: true,
                minWidth: '120'
            },
            {
              prop: 'address',
              label: '油站地址',
              sort: 1,
              show: true,
              minWidth: '120'
            },
            {
              prop: 'header',
              label: '油站负责人',
              sort: 1,
              show: true,
              minWidth: '120'
            },
            {
              prop: 'headerPhone',
              label: '负责人电话',
              sort: 1,
              show: true,
              minWidth: '120'
            },
            {
              prop: 'updateTime',
              label: '更新时间',
              sort: 1,
              show: true,
              minWidth: '120'
            }
          ],
          tableData: []
        }
    },
    mounted () {
        this.tableHeaderBackup = this.$tool._deepCopy(this.tableHeader)
        this.init()
    },
    methods: {
        init () {
            this.tableHeaderYes = this.tableHeaderBackup.filter(i => i.show)
            this.tableHeaderNo = this.tableHeaderBackup.filter(i => !i.show)
        },
        renderHeader (createElement, { column, $index }) {
          return createElement(
            'div',
            {
              class: ['thead-cell-box'],
              on: {
                mousedown: $event => {},
                mousemove: $event => {}
              }
            },
            [
              createElement(
                'span',
                {
                  class: ['thead-cell1']
                },
                column.label
              ),
              createElement('span', {
                class: ['thead-cell'],
                on: {
                  mousedown: $event => {
                    this.handleMouseDown($event, column)
                  },
                  mousemove: $event => {
                    this.handleMouseMove($event, column)
                  }
                }
              }),
              createElement(
                'span',
                {
                  class: {
                    'thead-cell2': true,
                    'caret-wrapper': true,
                    hidden: !this.tableHeaderYes[$index].sort,
                    ascending: this.tableHeaderYes[$index].sort === 2,
                    descending: this.tableHeaderYes[$index].sort === 3
                  },
                  on: {
                    click: $evnet => {
                      this.clickHandler($evnet, column, $index)
                    }
                  }
                },
                [
                  createElement(
                    'i',
                    {
                      class: ['sort-caret', 'ascending']
                    }
                  ),
                  createElement(
                    'i',
                    {
                      class: ['sort-caret', 'descending']
                    }
                  )
                ]
              )
            ]
          )
        },
        handleMouseDown (e, column) {
          this.dragState.dragging = true
          this.dragState.start = parseInt(column.columnKey)
          document.addEventListener('mouseup', this.handleMouseUp)
        },
    
        handleMouseUp () {
            // 初始化拖动状态
          this.dragState.start = -9
          this.dragState.end = -9
          this.dragState.dragging = false
          document.removeEventListener('mouseup', this.handleMouseUp)
        },
    
        handleMouseMove (e, column) {
          if (this.dragState.dragging) {
            let index = parseInt(column.columnKey) // 记录起始列
            if (index - this.dragState.start !== 0) {
                this.dragState.end = parseInt(column.columnKey)
                this.dragColumn(this.dragState) // 换位置
            }
          } else {
            return false
          }
        },
    
        dragColumn ({ start, end, direction }) {
          const tableHeaderYes = this.$tool._deepCopy(this.tableHeaderYes)
    
            //交换位置
            const startObj = tableHeaderYes[start]
            this.tableHeaderYes.splice(start, 1)
            this.tableHeaderYes.splice(end, 0, startObj)
          
            this.tableHeaderBackup = this.tableHeaderYes.concat(this.tableHeaderNo)//合并从新设置表头
            this.dragState.dragging = false
            this.$nextTick(() => {
              this.dragState.dragging = true
              this.dragState.start = end
              this.dragState.end = start
            })
          
    
        },
    
        // 拖拽样式的设置
        headerCellClassName ({ column, columnIndex }) {
          if (this.showSelection) columnIndex--
          if (this.showExpand) columnIndex--
          let active =
            columnIndex === this.dragState.end
              ? `darg_active_${this.dragState.direction}`
              : ''
          let start = columnIndex === this.dragState.start ? `darg_start` : ''
          return `${active} ${start}`
        },
        cellClassName ({ column, columnIndex }) {
          if (this.showSelection) columnIndex--
          if (this.showExpand) columnIndex--
          return columnIndex === this.dragState.start ? `darg_start` : ''
        },
        
        //打印包住区域
        print () {
            this.$refs.print.print()
        },
        
        // 点击表头排序回调事件 1是默认,2升序,3降序
        clickHandler (e, c, i) {
            this.tableHeaderYes.map((item, index) => {
                if (i === index) {
                  item.sort++
                  if (item.sort >= 4) {
                    item.sort = 1
                  }
                } else if (item.sort) {
                  item.sort = 1
                }
            })
            
            console.log(c.property, this.tableHeaderYes[i].sort)// 字段名,排序状态
            
        }
    }
}


复制代码
.w-table {
  position: relative;
  .edit {
    position: absolute;
    right: 0;
    top: 0;
    z-index: 10;
    .el-dropdown-link {
      cursor: pointer;
      background: #fff;
      color: #1890ff;
      font-size: 20px;
      border: 1px solid #dfe6ec;
      box-sizing: border-box;
      height: 40px;
      width: 40px;
      display: flex;
      justify-items: center;
      align-content: center;
    }

    i {
      margin: 0;
      width: 40px;
      text-align: center;
      line-height: 40px;
    }
  }
  .cell {
    transition: all ease 0.2s;
  }
  .el-table {
    thead {
      th{
        transition: all ease 0.2s;
      &:hover{
          background: #ddd;
        }
    }
      .cell{
        line-height: 40px;

      }
      .darg_start {
        background: #999 !important;
        cursor: move;
        .cell{
          color: #fff;
        }
      }
    }
  }
  .el-table th {
    padding: 0;
    .thead-cell-box {
        display: block;
        position: relative;
        white-space: normal;
    }
  .thead-cell {
    cursor:copy;
    position: absolute;
    top: 0;
    left: -10px;
    bottom: 0;
    right: 0;
  }
  .thead-cell2 {
    width: 35px;
  }
  .thead-cell1 {
    display: inline-block;
    position: relative;
    white-space: normal;
    font-weight: 800;
    line-height: 22px;
  }
  &.w-table_moving {
    .el-table th .thead-cell {
      cursor: move !important;
    }
    .el-table__fixed {
      cursor: not-allowed;
    }
  }
}

复制代码

搞完收工,200到手,下班下班,明天再来封装成组件app

转载记录地址连接

相关文章
相关标签/搜索