Vue中Sortable+多选框进行排序以及自定义列表是否展示

关于Sortable的安装详情可查看官网,此处不作解释

其他部分直接上代码

 代码部分

<template>
  <div class="content">
    <el-card style="margin-top: 5px;">
      <h1 style="font-weight: bolder;">调试</h1>
      <el-form :inline="true" ref="queryForm" :model="queryParams" class="demo-form-inline" filterable>
        <el-form-item>
          <el-input id="input" style="width: 330px;" v-model="queryParams.keyword" placeholder="搜索条件" :value="value"
            @keyup.enter.native="getInfo()">
          </el-input>
        </el-form-item>
        <el-select v-model="queryParams.status" style="width: 230px;margin-right: 10px;" placeholder="请选择状态">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value2"
            @keyup.enter.native="getInfo()">
          </el-option>
        </el-select>
        <el-form-item>
          <el-button type="primary" @click="search">搜索</el-button>
          <el-button @click="resetTable">重置</el-button>
        </el-form-item>
        <el-form-item style="float: right;">
          <!-- v-hasPermi="['automatic:driver:add']" -->
          <el-button type="primary" @click="insert">
            新增</el-button>
          <!--  v-hasPermi="['automatic:driver:remove']" -->
          <el-button type="danger" @click="remove">删除
          </el-button>
        </el-form-item>

      </el-form>
    </el-card>
    <!-- 基本信息  @selection-change="handleSelectionChange" -->
    <el-card style="margin: 1% auto;">
      <div slot="header" class="clearfix">
        <el-row>
          <el-col :span="12">
            <el-button plain icon="el-icon-download" size="mini" @click="handleExport" style="margin-right: 0.9375rem;">
              导出
            </el-button>
          </el-col>
          <el-col :span="12" style="text-align:end">
            <el-button plain size="mini" style="margin-right: 0.9375rem;">
              <el-popover title="选择展示列" trigger="click" width="30">
                <el-checkbox-group v-model="checkedCol" size="mini" class="el-icon-s-unfold">
                  <el-checkbox v-for="(item,index) in checkGroup" :key="index-1" :label="item" :value="item">
                  </el-checkbox>
                  <i class="el-icon-s-unfold"></i>
                </el-checkbox-group>
                <div slot="reference">列表项展示筛选<i class="el-icon-setting"></i></div>
              </el-popover>
            </el-button>
          </el-col>

        </el-row>
      </div>
      <el-table ref="multipleTable" :data="tableData" tooltip-effect="dark" @row-click="clickRow" row-key="id">
        <el-table-column type="selection" width="55%" fixed>
        </el-table-column>
        <!-- <el-table-column type="selection" :selectable="checkSelectable" align="center" width="55"></el-table-column> -->

        <el-table-column v-for="(item, index) in col" :key="`col_${index}`" :prop="dropCol[index].prop"
          :label="item.label" v-if="colData[index].isTrue" sortable>
        </el-table-column>

        <!-- <el-table-column label="操作" fixed="right">
          <template slot-scope="scope">
            <button size="mini" @click="remove(scope.$index,scope.row)">删除</button>
          </template>
        </el-table-column> -->
      </el-table>
      <!-- 分页 -->
      <pagination v-show="total > 0" :total="this.total" :page.sync="queryParams.pageNum"
        :limit.sync="queryParams.pageSize" @pagination="getAllInfo" :page-sizes="[50, 100, 200, 400]"
        layout="total, sizes, prev, pager, next, jumper" />
    </el-card>
  </div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
  name: "All",
  data() {
    return {
      value: '',
      // 选中数组
      //id
      IDS: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      //获取表格数据
      // tableData: [],
      tableData: [
        {
          id: '1',
          date: '2016-05-02',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 100 弄'
        },
        {
          id: '2',
          date: '2016-05-04',
          name: '王小虎2',
          address: '上海市普陀区金沙江路 200 弄'
        },
        {
          id: '3',
          date: '2016-05-01',
          name: '王小虎3',
          address: '上海市普陀区金沙江路 300 弄'
        },
        {
          id: '4',
          date: '2016-05-03',
          name: '王小虎4',
          address: '上海市普陀区金沙江路 400 弄'
        }
      ],
      // 是否展示
      colData: [
        { title: "字段ID", isTrue: true },
        { title: "日期", isTrue: true },
        { title: "姓名", isTrue: true },
        { title: "地址", isTrue: true }

      ],
      //过滤,是否显示
      checkGroup: ['字段ID', '日期', '姓名', '地址'],
      // 是否默认选择
      checkedCol: ['字段ID', '日期', '姓名', '地址'],
      col: [
        {
          label: '字段ID',
          prop: 'id'
        },
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      dropCol: [
        {
          label: '字段ID',
          prop: 'id'
        },
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }

      ],

      //查询参数
      total: 0,
      queryParams: {
        keyword: "",
        pageNum: 1,
        BorrowMoneyNo: "",
        pageSize: 50,
        status: ""
      },
      multipleTable: [],
      options: [{
        value2: '选项1',
        label: '选项1'
      }, {
        value2: '选项2',
        label: '选项2'
      }, {
        value2: '选项3',
        label: '选项3'
      }, {
        value2: '选项4',
        label: '选项4'
      }, {
        value2: '选项5',
        label: '选项5'
      }],
      value2: ''
    };
  },
  // 监听
  watch: {
    // checkedCol(val) {
    //   let arr = this.checkGroup.filter(i => !val.includes(i)); // 未选中
    //   this.colData.filter(i => {
    //     if (arr.indexOf(i.title) != -1) {
    //       i.isTrue = false;
    //     } else {
    //       i.isTrue = true;
    //     }
    //   });
    // },
    checkedCol(val) {
      if (val) {
        let arr = this.checkGroup.filter(i => val.indexOf(i) < 0);//取出被选择的项
        this.colData.filter(i => {//显示列表过滤
          if (arr.indexOf(i.title) > -1) {//当选择的值匹配时不显示
            i.isTrue = false
          } else {
            i.isTrue = true
          }
        })
      }
    }
  },
  // components: { draggable },
  methods: {
    // checkSelectable(row) {
    //   if (row.id !== 5) {
    //     return true
    //   }
    // },
    // 行拖拽
    rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0]
          _this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },
    //列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: evt => {
          // 因为手动加了一个多选框, 不在表头循环数组内, 所以减1
          const oldItem = this.dropCol[evt.oldIndex - 1]
          // console.log(oldItem)
          // 真正改变列数据--变化列头,就能实现列拖动 列数据按列头索引取值 {{ scope.row[dropCol[index].prop] }}
          this.dropCol.splice(evt.oldIndex - 1, 1)// 删除旧一行 删除为1
          this.dropCol.splice(evt.newIndex - 1, 0, oldItem)// 插入新一行 插入为0
        }
      })
    },
    //点击一行中的任意位置进行复选框选中
    clickRow(row) {
      this.$refs.multipleTable.toggleRowSelection(row);
      // console.log(row)
    },
    //搜索按钮
    search() {

    },
    getInfo() {

    },
    //表单重置
    reset() {
      this.queryParams.keyword = ""
      this.queryParams.status = ""
    },
    //重置按钮操作
    resetTable() {
      this.reset()
      this.getAllInfo()
    },
    //查询全部货运支付信息
    getAllInfo() {

    },
    // 新增
    insert() {

    },
    // 删除
    remove(index, row) {
      console.log(row.id)
    },

    // 多选框选中数据
    handleSelectionChange(selection) {
      this.IDS = selection.map(item => item.id);
      console.log(this.IDS);
      console.log(this)
      this.single = selection.length != 1;
      this.multiple = !selection.length;
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },

    handleRemove(file, fileList) {
      console.log(file, fileList);
    },

    handlePreview(file) {
      console.log(file);
    },
    // 名字中文排序
    onSortChange({ prop, order }) {
      console.log(prop)
      if (prop == 'DriverName') {
        this.tableData.sort(this.compare(prop, order));
      }

    },
    compare(propertyName, sort) {
      return function (obj1, obj2) {
        var value1 = obj1[propertyName];
        var value2 = obj2[propertyName];
        if (typeof value1 === "string" && typeof value2 === "string") {
          const res = value1.localeCompare(value2, "zh");
          return sort === "ascending" ? res : -res;
        } else {
          if (value1 <= value2) {
            return sort === "ascending" ? -1 : 1;
          } else if (value1 > value2) {
            return sort === "ascending" ? 1 : -1;
          }
        }
      };
    },
    handleExport() {
      // this.download('接口', {
      //     ...this.queryParams
      //   }, `标题${new Date().getTime()}.xlsx`)
    },
  },

  mounted() {
    this.getAllInfo() //全部信息
    // 阻止默认行为
    document.body.ondrop = function (event) {
      event.preventDefault();
      event.stopPropagation();
    };
    this.rowDrop()
    this.columnDrop()

  }
}
</script>

<style scoped>
.time {
  font-size: 13px;
  color: #999;
}

.bottom {
  margin-top: 13px;
  line-height: 12px;
}

.button {
  padding: 0;
  float: right;
}

.image {
  width: 100%;
  display: block;
}

.clearfix:before,
.clearfix:after {
  display: table;
  content: "";
}

.clearfix:after {
  clear: both
}

.upLoad {
  width: 100%;
  text-align: left;
}

.demo-table-expand {
  font-size: 0;
}

.demo-table-expand label {
  width: 90px;
  color: #99a9bf;
}

.demo-table-expand .el-form-item {
  margin-right: 0;
  margin-bottom: 0;
  text-align: left;
}

.el-col-8 {
  text-align: left;
}

.el-col-24 {
  text-align: left;
}

.el-table tr {
  font-size: 13px;
  color: black;
}

.el-table el-table--fit el-table--scrollable-y el-table--enable-row-hover el-table--enable-row-transition el-table--medium {
  height: 400px;
}
</style>

效果图展示

原图

筛选展示

排序 

 

 

 

但是这个方法目前有一个bug,就是当我们进行列表拖拽或者筛选是否展示的时候,无论是先拖拽后筛选展示还是先筛选展示再进行拖拽都会出现乱序,请各位大佬帮忙解决一下

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值