基于draggable.js拖拽表格

<template>
  <div class="table-container">

    <table>
      <thead>
        <tr>
          <!-- 表头 -->
          <th v-for="(header, index) in headers" :key="index" :draggable="header.sortable" @dragstart="startDrag(index)"
            @dragover="dragOver" @drop="drop(index)" :style="{ width: header.width }" style="padding: 0 5px;">
            <template v-if="header.desc">
              <div class="header-box" :style="{ justifyContent: header.textAlign }" style="display: flex;">
                <span @click="onclick">{{ header.text }}</span>
                <span class="svgcont" v-if="header.upSVGVisible & header.downSVGVisible">
                  <svg width="6" height="6" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" @click="up(index)"
                    v-if="header.upSVGVisible">
                    <polygon points="50,10 90,90 10,90" fill="grey" />
                  </svg>
                  <svg width="6" height="6" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" @click="down(index)"
                    v-if="header.downSVGVisible">
                    <polygon points="50,90 90,10 10,10" fill="grey" />
                  </svg>
                </span>
                <!-- 上箭头 -->
                <span class="svgcont" v-if="header.upSVGVisible & !header.downSVGVisible">
                  <svg width="8" height="8" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" @click="up(index)">
                    <polygon points="50,10 90,90 10,90" fill="white" />
                  </svg>
                </span>

                <!-- 下箭头点击 -->
                <span class="svgcont" v-if="header.downSVGVisible & !header.upSVGVisible">
                  <svg width="8" height="8" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" @click="down(index)">
                    <polygon points="50,90 90,10 10,10" fill="white" />
                  </svg>
                </span>
              </div>
            </template>
            <template v-else>
              <div class="header-box" :style="{ justifyContent: header.textAlign }" style="display: flex;">
                <span>{{ header.text }}</span>
              </div>
            </template>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="(row, rowIndex) in tableData" :key="rowIndex" :class="{ odd: rowIndex % 2 === 0 }">
          <td v-for="(cell, cellIndex) in row" :key="cellIndex" :style="{
            textAlign: cellTextAlign(cellIndex),
            borderRight: '1px solid #13161A',
            padding: '0 5px',
            cursor: 'default',
            color: cellColor(cellIndex)
          }" :title="`${cell}`">
            {{ cell }}
          </td>
        </tr>

      </tbody>
    </table>

  </div>
</template>

<script>
export default {
  data() {
    return {
      // 表头数据
      headers: [
        {
          text: '日期/时间', dataIndex: 0, sortable: true, width: '139px', desc: true, textAlign: 'flex-start', upSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
          downSVGVisible: true,
        },
        {
          text: '类型', dataIndex: 1, sortable: true, width: '202px', desc: true, textAlign: 'flex-start', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '订单号', dataIndex: 2, sortable: true, width: '99px', desc: true, textAlign: 'flex-start', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '交易号', dataIndex: 3, sortable: true, width: '99px', desc: true, textAlign: 'flex-start', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '相关订单号', dataIndex: 4, sortable: true, width: '118px', desc: true, textAlign: 'flex-start', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '产品', dataIndex: 5, sortable: true, width: '326px', desc: true, textAlign: 'flex-star', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        { text: '数量/金额', dataIndex: 6, sortable: true, width: '99px', textAlign: 'flex-end' },
        {
          text: '价格', dataIndex: 7, sortable: true, width: '99px', desc: true, textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '止损', dataIndex: 8, sortable: true, width: '99px', textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '获利', dataIndex: 9, sortable: true, width: '99px', textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true,// 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '兑换率', dataIndex: 10, sortable: true, width: '139px', textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '价值', dataIndex: 11, sortable: true, width: '99px', desc: true, textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '金额', dataIndex: 12, sortable: true, width: '99px', desc: true, textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true,// 控制上箭头 SVG 的显示与隐藏
        },
        {
          text: '余额', dataIndex: 13, sortable: true, width: '101px', desc: true, textAlign: 'flex-end', upSVGVisible: true, downSVGVisible: true, // 控制上箭头 SVG 的显示与隐藏
        },
      ],
      // 表格数据
      tableData: [
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],
        ['内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2', '内容3', '内容1', '内容2'],


      ],
      // 正在拖动的列的索引
      draggingColumnIndex: null,
      show: false,
    }
  },

  methods: {
    // 拖动开始事件处理函数
    startDrag(index) {
      this.draggingColumnIndex = index;
    },
    // 拖动到目标区域事件处理函数
    dragOver(event) {
      event.preventDefault();
    },
    // 放置拖动列的目标位置事件处理函数
    drop(index) {
      if (this.draggingColumnIndex !== null) {
        // 交换表头位置
        const movedHeader = this.headers.splice(this.draggingColumnIndex, 1)[0];
        this.headers.splice(index, 0, movedHeader);

        // 交换对应内容位置
        this.tableData.forEach(row => {
          const movedCell = row.splice(this.draggingColumnIndex, 1)[0];
          row.splice(index, 0, movedCell);
        });
        this.draggingColumnIndex = null;
      }
    },
    onclick() {
      console.log(1);
      //这里做排序事件
    },
    cellTextAlign(cellIndex) {

      return this.headers[cellIndex].dataIndex >= 6 ? 'right' : 'left';
    },
    cellColor(cellIndex) {
      const dataIndex = this.headers[cellIndex].dataIndex;
      if (dataIndex === 8) {
        return '#FF443D';
      } else if (dataIndex === 9) {
        return '#07E11C';
      } else {
        return '#fff';
      }
    },

    up(index) {
      // 上箭头点击事件处理函数
      // 这里根据 index 控制要显示的 SVG
      this.headers.forEach((header, i) => {
        if (i !== index) {
          header.upSVGVisible = true;
          header.downSVGVisible = true;
        }
      });
      this.headers[index].upSVGVisible = false;
      this.headers[index].downSVGVisible = true;
    },
    down(index) {
      // 下箭头点击事件处理函数
      // 这里根据 index 控制要显示的 SVG
      this.headers.forEach((header, i) => {
        if (i !== index) {
          header.upSVGVisible = true;
          header.downSVGVisible = true;
        }
      });
      this.headers[index].upSVGVisible = true;
      this.headers[index].downSVGVisible = false;

    },

  },
};
</script>

<style scoped>
/* 根据需要自定义样式 */
th {
  height: 23px;
  position: sticky;
  top: 0;
}

th,
td {


  font-size: 10px;
  color: #FFFFFF;
  text-align: left;
}

th {
  height: 23px;
  background: #13161A;
  border-right: 1px solid #292D31;
}

tr.odd {

  background: #111A24;
  /* 奇数行设置黄色背景色 */
}

.table-container {
  max-height: 100vh;
  /* 设置最大高度 */
  overflow-y: auto;
  /* 垂直滚动条 */

}

.table-container {
  /* 自定义滚动条样式 */
  scrollbar-width: thin;
  /* 设置滚动条宽度 */
  scrollbar-color: #282E35 #3D4651;
  /* 设置滚动条颜色,第一个参数是滚动条轨道颜色,第二个参数是滚动条滑块颜色 */
}

/* Webkit 内核浏览器的滚动条样式 */
/* ::-webkit-scrollbar 是 Webkit 内核浏览器的伪类 */
/* 使用 ::-webkit-scrollbar 进行样式设置 */
.table-container::-webkit-scrollbar {
  width: 4px;
  /* 设置滚动条宽度 */
}

/* 设置滚动条轨道的样式 */
.table-container::-webkit-scrollbar-track {
  background-color: #282E35;
  /* 设置滚动条轨道颜色 */
  width: 12px;
}

.table-container::-webkit-scrollbar {
  width: 16px !important
}

/* 设置滚动条滑块的样式 */
.table-container::-webkit-scrollbar-thumb {
  background-color: #3D4651;
  /* 设置滚动条滑块颜色 */
  border-radius: 4px;
  /* 设置滚动条滑块的圆角 */
}

.svgcont {
  display: flex;
  flex-direction: column;
  margin-left: 3px;
  justify-content: center;
}
</style>

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值