vuetify表格自定义拖拽排序

图例:

 

 

1、首先安装sortablejs

npm install sortablejs

2、页面引入

<template>
  <div id="standardAssay">
    <div class="tabListOne">
      <v-card class="mx-auto">
        <div class="tableTitle">
          <div class="titleName">标准检测项目配置</div>
          <div class="titleBtn">
            <div v-if="ifEdit">
              <v-btn
                dark
                width="96"
                height="40"
                color="#0B41CD"
                dense
                hide-details
                style="color: #fff"
                @click="itemEdit"
              >
                <v-icon dark left dense>mdi-pencil-box-outline</v-icon> 编辑
              </v-btn>
            </div>
            <div v-if="!ifEdit">
              <v-btn
                dark
                width="96"
                height="40"
                color="#0B41CD"
                dense
                hide-details
                style="color: #fff"
                :loading="isSaveData"
                @click="itemSave"
              >
                保存
              </v-btn>
              <v-btn
                dark
                width="96"
                height="40"
                outlined
                color="indigo"
                dense
                hide-details
                style="margin-left: 16px"
                @click="itemCancel"
              >
                取消
              </v-btn>
            </div>
          </div>
        </div>
        <v-data-table
          :headers="tableDataHead"
          :items="tableDataList"
          :items-per-page="10"
          class="elevation-1 tableAllStyl"
          :server-items-length="total"
          hide-default-footer
          :loading="isData"
          id="tableRowDrop"
          disable-sort
          item-key="sortId"
        >
          <template v-slot:[`item.sort`]="{ item }">
            <div class="sortStyl">
              <span class="sortName">{{ item.sort }}</span>
              <span class="iconRisk"
                ><v-icon size="20" color="#9e9e9e">mdi-menu</v-icon></span
              >
            </div>
          </template>
          <template v-slot:[`item.dataType`]="{ item }">
            <div>
              {{
                item.dataType === 1
                  ? "数值"
                  : item.dataType === 2
                  ? "文本"
                  : "-"
              }}
            </div>
          </template>
          <template v-slot:[`item.isStatistics`]="{ item }">
            <div v-if="!ifEdit">
              <el-radio-group v-model="item.isStatistics">
                <el-radio :label="1">是</el-radio>
                <el-radio :label="0">否</el-radio>
              </el-radio-group>
            </div>
            <div v-if="ifEdit">{{ item.isStatistics === 1 ? "是" : "否" }}</div>
          </template>
          <template v-slot:[`item.detail`]="{ item }">
            <div v-show="item.conclusionOption">
              <el-popover placement="left-end" width="200" trigger="click">
                <div class="viewConclu">
                  <div class="concluTopName">
                    <div>结论</div>
                    <div>是否异常</div>
                  </div>
                  <div class="concluBtmCont">
                    <div
                      class="btmContLi"
                      v-for="(item, index) in item.conclusionOptionNew"
                      :key="index"
                    >
                      <div>{{ item.label }}</div>
                      <div>
                        <span v-show="item.status === 1" style="color: #212631"
                          >正常</span
                        >
                        <span v-show="item.status === 0" style="color: #c80000"
                          >异常</span
                        >
                      </div>
                    </div>
                  </div>
                </div>
                <span
                  slot="reference"
                  style="color: #0b41cd; padding: 0 8px; cursor: pointer"
                  >查看</span
                >
              </el-popover>
            </div>
            <div v-show="!item.conclusionOption">-</div>
          </template>
        </v-data-table>
      </v-card>
    </div>
  </div>
</template>

<script>
import {
  getStandandItem, getStandSubmit
} from '@/api/limitApi/index.js'
import SortableRow from 'sortablejs'
export default {
  name: 'standardAssay',
  components: {},
  computed: {

  },
  data: () => ({
    isSaveData: false,
    ifEdit: true,
    isData: false,
    total: 0,
    tableDataHead: [
      {
        text: '111',
        align: 'start',
        value: 'code'
      },
      { text: '222', value: 'name' },
      { text: '333', value: 'hpCode' },
      { text: '444', value: 'hpName' },
      { text: '555', value: 'dataType' },
      { text: '666', value: 'unit' },
      { text: '777', value: 'valueRange' },
      { text: '888', value: 'isStatistics', width: '150' },
      { text: '999', value: 'sort' },
      { text: '100', value: 'detail' }
    ],
    tableDataList: [],
    rowSort: null,
    itemListJson: []
  }),
  created() {

  },
  mounted() {
    this.getDataPage()
    document.body.ondrop = function (event) {
      event.preventDefault()
      event.stopPropagation()
    }
  },
  methods: {
    itemEdit() {
      this.ifEdit = false
      this.rowDrop()
    },
    async itemSave() {
      this.ifEdit = false
      this.itemListJson = []
      this.tableDataList.forEach((item, index) => {
        this.itemListJson.push({
          code: item.code,
          isStatistics: item.isStatistics,
          sort: index + 1
        })
      })
      await this.itemSaveSubmit()
    },
    itemSaveSubmit() {
      const data = {
        listJson: JSON.stringify(this.itemListJson)
      }
      this.isSaveData = true
      getStandSubmit(data).then(
        (resp) => {
          if (resp.code === 0) {
            this.$message({
              message: '保存成功',
              type: 'success'
            })
            this.ifEdit = true
            this.rowSort.destroy()
            this.getDataPage()
          } else {
            this.$message.error(resp.errorMessage)
          }
          this.isSaveData = false
        },
        (error) => {
          this.isSaveData = false
          this.$message.error(error)
        }
      )
    },
    itemCancel() {
      this.ifEdit = true
      this.rowSort.destroy()
      this.getDataPage()
    },
    rowDrop() {
      const tbody = document.querySelector('#tableRowDrop tbody'),
        self = this
      this.rowSort = SortableRow.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          const [currRow] = self.tableDataList.splice(oldIndex, 1)
          self.tableDataList.splice(newIndex, 0, currRow)
        }
      })
    },
    getLimit(perms) {
      return limitFn(perms)
    },
    getDataPage() {
      this.isData = true
      this.tableDataList = []
      const data = {
        typeList: [1, 2]
      }
      getStandandItem(data).then(
        (resp) => {
          if (resp.code === 0) {
            this.tableDataList = resp.payload
            for (let i = 0; i < this.tableDataList.length; i += 1) {
              this.tableDataList[i].sortId = i + 1
            }
            this.tableDataList.forEach((item) => {
              if (item.normalRangeStart !== undefined && item.normalRangeEnd !== undefined) {
                item.valueRange = `${item.normalRangeStart} - ${item.normalRangeEnd}`
              } else {
                item.valueRange = '-'
              }
              if (item.conclusionOption !== undefined) {
                item.conclusionOptionNew = JSON.parse(item.conclusionOption)
              }
              if (!item.hpCode) {
                item.hpCode = '-'
              }
              if (!item.hpName) {
                item.hpName = '-'
              }
              if (!item.unit) {
                item.unit = '-'
              }
            })
            this.total = resp.payload.length
          } else {
            this.$message.error(resp.errorMessage)
          }
          this.isData = false
        },
        (error) => {
          this.isData = false
          this.$message.error(error)
        }
      )
    }
  },
  destroyed() {

  }
}
</script>

<style lang="less" scoped>
.viewConclu {
  display: flex;
  flex-direction: column;
  padding: 6px;
  .concluTopName {
    display: flex;
    justify-content: space-between;
    color: #212631;
    font-size: 14px;
    font-weight: 700;
    margin-bottom: 10px;
  }
  .concluBtmCont {
    display: flex;
    flex-direction: column;
    .btmContLi {
      display: flex;
      justify-content: space-between;
      color: #212631;
      font-size: 14px;
      margin-bottom: 16px;
    }
  }
}
.sortStyl {
  width: 60px;
  display: flex;
  .sortName {
    min-width: 32px;
  }
}
.tableAllStyl {
  ::v-deep tbody {
    tr {
      cursor: move;
    }
  }
  ::v-deep .v-data-table__wrapper {
    max-height: 2000px !important;
  }
}
.tableTitle {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 26px 24px 80px;
  box-sizing: border-box;
  .titleName {
    font-size: 26px;
    color: #212631;
    font-weight: 700;
  }
}
a {
  text-decoration: none;
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现表格行的拖拽排序,可以考虑以下步骤: 1. 给每一行添加一个可拖拽的属性,例如设置行的 draggable 属性为 true。 2. 监听行的拖拽事件,当拖拽开始时,记录被拖拽的行的位置和数据。 3. 监听拖拽过程事件,计算拖拽行与其它行的位置关系,根据位置关系决定拖拽行的插入位置。 4. 监听拖拽结束事件,根据插入位置将拖拽行插入到表格中,并更新表格中其它行的位置。 具体实现可以参考以下代码: ```html <table id="sortable-table"> <thead> <tr> <th>Name</th> <th>Age</th> <th>Country</th> </tr> </thead> <tbody> <tr draggable="true"> <td>Alice</td> <td>25</td> <td>USA</td> </tr> <tr draggable="true"> <td>Bob</td> <td>30</td> <td>Canada</td> </tr> <tr draggable="true"> <td>Charlie</td> <td>20</td> <td>UK</td> </tr> </tbody> </table> ``` ```javascript const table = document.getElementById('sortable-table'); let draggedRow = null; table.addEventListener('dragstart', e => { draggedRow = e.target.parentNode; e.dataTransfer.setData('text/html', e.target.innerHTML); }); table.addEventListener('dragover', e => { e.preventDefault(); const targetRow = e.target.parentNode; if (targetRow !== draggedRow) { const rect = targetRow.getBoundingClientRect(); const isAfter = e.clientY > rect.top + rect.height / 2; table.insertBefore(draggedRow, isAfter ? targetRow.nextSibling : targetRow); } }); table.addEventListener('dragend', () => { draggedRow = null; }); ``` 在这个示例代码中,我们给表格中的每一行添加了 draggable 属性,并分别监听了 dragstart、dragover 和 dragend 事件,实现了表格行的拖拽排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值