vue + element 引用sortablejs实现列显隐和拖拽功能

在vue + elementui 项目中,为满足用户不同的操作习惯,可自定义列表字段的排列

  1. 安装sortablejs:

   Npm install sortablejs --save

  1. 代码部分

  列表字段部分,可通过选中和取消,实现列表字段列显隐,是否展示或者隐藏,可通过拖动字段的顺序来实现自定义排版

遍历展示表格字段:

定义字段,和table  表格的字段:

ColList  为要调整的字段的初始化状态

ColData  为表格的字段初始顺序

Mouted  中复制一份数据,调用拖拽的方法:columnDrop:

若需要恢复默认功能 ,可将colData  恢复到初始状态,也可将调整后的字段顺序和列显隐 调接口保存,下次登录进来查询得到自定义的序列

效果图:

主要代码:

<!-- 采购结算 -->

<template>

  <div class="container">

    <el-form

      :model="paramsForm"

      label-position="left"

      label-width="80px"

      @keyup.enter.native="search">

      <el-row :gutter="10">

     

      </el-row>

    </el-form>

    <el-row class="last-row">

      <el-button type="primary" icon="el-icon-search" @click="search">

        查询

      </el-button>

      <el-button type="info" icon="el-icon-close" @click="reset">

        重置

      </el-button>

      <el-button type="primary" icon="el-icon-download" @click="exportList">

        导出Excel

      </el-button>

      <el-button type="primary" icon="el-icon-download" @click="batchSettle">

        批量结算确认

      </el-button>

      <el-popover placement="bottom-start" :width="600" style="height: 500px;" trigger="hover">

        <transition name="fade">

          <div id="dropItem">

            <!-- <el-checkbox v-model="checkAll" @change="handleCheckAllChange">全选</el-checkbox> -->

            <el-checkbox v-for="(item, index) in colList" :key="index" @change="handleCheckedBoxChange(item)" v-model="item.status">{{item.title}}</el-checkbox>

          </div>

        </transition>

        <template #reference>

          <el-button style="float: right;" type="primary">列表布局调整</el-button>

        </template>

      </el-popover>

    </el-row>

    <el-table

      ref="tableRef"

      id="tab1"

      v-loading="loading"

      fit

      border

      :data="tableData"

      :height="tableHeight"

      show-summary

      :summary-method="getSummaries"

      :cell-class-name="cellStyle"

      @select-all="selectItem"

      @select="selectItem"

      @sort-change="tableSortChange">

      <el-table-column v-slot="scope" max-width="50" type="index" label="序号">

        <span>{{ scope.$index + (params.page - 1) * params.rows + 1 }}</span>

      </el-table-column>

      <el-table-column type="selection" :selectable="checkSelectable"  width="60" :show-overflow-tooltip="true"/>

      <el-table-column v-slot="scope" max-width="80" label="操作">

        <span v-if="scope.row.confirm_status == 0" class="table-operate" @click="returnHandler(scope.row)">

          结算确认

        </span>

      </el-table-column>

      <template v-for="(item,index) in colData">

          <el-table-column

            :width="item.width"

            :label="item.title"

            :key="index"

            v-if="colData[index].status"

            v-slot="scope"

            align="center">

            <a v-if="scope.row.return_num >= 0 && item.prop == 'order_sn'" @click="handleDetail(scope.row)">

            {{ scope.row.order_sn }}

            </a>

            <span v-else> {{scope.row[item.prop]}}</span>

          </el-table-column>

       </template>

    </el-table>

    <el-row class="pagination-row">

      <el-col :span="16">

        <Pagination

          :total="params.total"

          :page.sync="params.page"

          :limit.sync="params.rows"

          @pagination="getList" />

      </el-col>

      <el-col :span="8" class="table-col-show">

        <div>

          <el-button size="mini" type="primary" @click="saveColData">

            保存

          </el-button>

          <el-button size="mini" type="info" @click="resetColumnData">

            恢复默认

          </el-button>

        </div>

        <!-- <TableColShowOrHide ref="tableColShowOrHideRef" :col-data="colData" /> -->

      </el-col>

    </el-row>

  </div>

</template>

<script>

import Pagination from '@/components/Pagination'

import { tableEditColumn } from '@/utils/tableEditColumn'

import { getR, postR, exportExcelR } from '@/utils/requestCustomer'

import TableColShowOrHide from '@/components/TableColShowOrHide'

import Sortable from 'sortablejs'

export default {

  // eslint-disable-next-line vue/name-property-casing

  name: '',

  components: {

    Pagination,

    TableColShowOrHide

  },

  mixins: [tableEditColumn],

  data() {

    return {

      tableName: 'queryBySupplierPurchase',

      supplierDetailVisible: false,

      tableHeight: document.documentElement.clientHeight - 310,

      paramsForm: {   },

      loading: false,

      tableData: [],

      params: {

        // 分页数据

        page: 1,

        rows: 10,

        total: 0

      },

      totalFooter: {},

      checkedList: [],

      newColumnList: [],

      colList: [

        { title: '采购单号', prop: "order_sn",width:'130', status: true },

        { title: '确认时间', prop: "confirm_time",width:'120', status: true },

        { title: '供应商', prop: "cus_name",width:'100',  status: true },

        { title: '联系人', prop: "contact_name",width:'100', status: true },

        { title: '电话', prop: "contact_phone",width:'100', status: true },

        { title: '税率', prop: "tax_rate",width:'80', status: true },

        { title: '金额(不含税)', prop: "amount_no_tax",width:'140', status: true },

        { title: '税额', prop: "tax_amount",width:'80', status: true },

        { title: '金额(含税)', prop: "amount_tax",width:'100', status: true },

        { title: '优惠金额', prop: "discount",width:'100', status: true },

        { title: '开票状态', prop: "vote_status_name",width:'100', status: true },

        { title: '发票号码', prop: "vote_code",width:'100', status: true },

        { title: '开票时间', prop: "vote_time",width:'200', status: true },

        { title: '结算时间', prop: "pre_time",width:'120', status: true },

        { title: '结算方式', prop: "set_name",width:'110', status: true },

        { title: '结算操作人', prop: "pre_realname",width:'110', status: true },

        { title: '确认操作人', prop: "confirm_user",width:'110',  status: true }

      ],

      colData: [

        { title: '采购单号', prop: "order_sn",width:'130', status: true },

        { title: '确认时间', prop: "confirm_time",width:'120', status: true },

        { title: '供应商', prop: "cus_name",width:'100',  status: true },

        { title: '联系人', prop: "contact_name",width:'100', status: true },

        { title: '电话', prop: "contact_phone",width:'100', status: true },

        { title: '税率', prop: "tax_rate",width:'80', status: true },

        { title: '金额(不含税)', prop: "amount_no_tax",width:'140', status: true },

        { title: '税额', prop: "tax_amount",width:'80', status: true },

        { title: '金额(含税)', prop: "amount_tax",width:'100', status: true },

        { title: '优惠金额', prop: "discount",width:'100', status: true },

        { title: '开票状态', prop: "vote_status_name",width:'100', status: true },

        { title: '发票号码', prop: "vote_code",width:'100', status: true },

        { title: '开票时间', prop: "vote_time",width:'200', status: true },

        { title: '结算时间', prop: "pre_time",width:'120', status: true },

        { title: '结算方式', prop: "set_name",width:'110', status: true },

        { title: '结算操作人', prop: "pre_realname",width:'110', status: true },

        { title: '确认操作人', prop: "confirm_user",width:'110',  status: true }

      ]

    }

  },

  mounted() {

    this.search()

    this.newColumnList = JSON.parse(JSON.stringify(this.colList))

    this.columnDrop()

  },

  methods: {

    getList() {

      this.loading = true

      getR('/api/web/pur/fin/confirm', { ...this.paramsForm, ...this.params })

        .then(res => {

          this.tableData = res.result.rows

          this.params.total = res.result.total

          this.totalFooter = res.result.footer[0]

        })

        .finally(() => {

          this.loading = false

        })

    },

    search() {

      if ((this.pre_time == null || this.pre_time == [] || this.pre_time == '') && (this.confirm_time == null || this.confirm_time == [] || this.confirm_time == '')) {

        this.$message({

          message: '请选择结算日期范围/确认日期范围!',

          type: 'warning'

        })

      } else {

        this.params.page = 1

        this.getList()

      }

    },

    reset() {

      Object.keys(this.paramsForm).forEach(k => {

        this.paramsForm[k] = ''

      })

      this.pre_time = [this.dyDate.getLastMonthTime(), this.dyDate.getNowTime()]

      this.vote_time = []

      this.confirm_time = []

      this.dataPickChange('pre')

      this.cusDisabled = false

      this.paramsForm.is_merged = false

      this.paramsForm.confirm_status = 0

      this.search()

    },

    resetColumnData() {

      this.colData = [

        { title: '采购单号', prop: "order_sn",width:'130', status: true },

        { title: '确认时间', prop: "confirm_time",width:'120', status: true },

        { title: '供应商', prop: "cus_name",width:'100',  status: true },

        { title: '联系人', prop: "contact_name",width:'100', status: true },

        { title: '电话', prop: "contact_phone",width:'100', status: true },

        { title: '税率', prop: "tax_rate",width:'80', status: true },

        { title: '金额(不含税)', prop: "amount_no_tax",width:'140', status: true },

        { title: '税额', prop: "tax_amount",width:'80', status: true },

        { title: '金额(含税)', prop: "amount_tax",width:'100', status: true },

        { title: '优惠金额', prop: "discount",width:'100', status: true },

        { title: '开票状态', prop: "vote_status_name",width:'100', status: true },

        { title: '发票号码', prop: "vote_code",width:'100', status: true },

        { title: '开票时间', prop: "vote_time",width:'200', status: true },

        { title: '结算时间', prop: "pre_time",width:'120', status: true },

        { title: '结算方式', prop: "set_name",width:'110', status: true },

        { title: '结算操作人', prop: "pre_realname",width:'110', status: true },

        { title: '确认操作人', prop: "confirm_user",width:'110',  status: true }

      ]

      this.recoveryColData()

    },

    // 合计

    getSummaries(param) {

      const { columns } = param

      const sums = []

      columns.forEach((column, index) => {

        if (index === 0) {

          sums[index] = '合计'

          return

        }

        if (column.property === 'amount_no_tax' || column.label === '金额(不含税)') {

          sums[index] = this.totalFooter.amount_no_tax

          return

        }

        if (column.property === 'amount_tax' || column.label === '金额(含税)') {

          sums[index] = this.totalFooter.amount_tax

          return

        }

        if (column.property === 'tax_amount' || column.label === '税额') {

          sums[index] = this.totalFooter.tax_amount

          return

        }

        if (column.property === 'discount' || column.label === '优惠金额') {

          sums[index] = this.totalFooter.discount

          return

        }

      })

      this.$nextTick(() => {

        this.$refs.tableRef.doLayout()

      })

      return sums

    },

    // 排序

    tableSortChange(column) {

      if (column.order === 'descending') {

        this.paramsForm.sort = column.prop

        this.paramsForm.order = 'desc'

      } else if (column.order === 'ascending') {

        this.paramsForm.sort = column.prop

        this.paramsForm.order = 'asc'

      } else {

        this.paramsForm.sort = column.prop

        this.paramsForm.order = ''

      }

      this.getList()

    },

    //拖拽

    columnDrop() {

      const wrapperTr = document.getElementById('dropItem')

      this.sortable = Sortable.create(wrapperTr, {

        animation: 180,

        delay: 0,

        onEnd: (evt) => {

          const oldItem = this.colData[evt.oldIndex];

          this.colData.splice(evt.oldIndex, 1);// 移动

          this.colData.splice(evt.newIndex, 0, oldItem);

          console.log(this.colData)

          this.getList()

        },

      });

    },

    handleCheckedBoxChange(item) {

        this.colData.forEach(i => {

            if(i.title==item.title){

                i.status=item.status

            }

        });

        return this.colData

    },

  }

}

</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值