记录vue开发中使用表格拖动

来看两张效果图,首先来看保存前的数据

在这里插入图片描述

再看保存后的数据

在这里插入图片描述
其原理简单来说就是,改变了对象数组的某一项在原数据中所在的位置,比如:将数组下标为0的数据和下标为1的数据更换了位置,相当于排序一样的逻辑,然后再把更换后的新数据保存到后台。

接下来看使用方法,首先安装相关依赖

npm install lodash // 用于表单提交时的防抖节流
npm install sortablejs // 表格拖动相关依赖
npm install vxe-table // 支持拖动的表格

在使用的页面中引入

import debounce from 'lodash/debounce' // 用于表单提交时的防抖节流
import Sortable from 'sortablejs'

下面定义子组件:

<template>
	<el-dialog
	  class="enterDialog"
	  :title="!dataForm.id ? $t('add') : $t('update')"
	  width="53%"
	  :visible.sync="addVisible"
	>
		<vxe-table
		  border
		  row-key
		  ref="xTable"
		  class="sortable-row-gen"
		  size="mini"
		  :data="watchList"
		  :checkbox-config="{ checkStrictly: true }"
		  :edit-config="{
		    trigger: 'click',
		    mode: 'cell',
		    icon: 'fa fa-pencil'
		  }"
		>
		  <vxe-table-column type="seq" width="35"></vxe-table-column>
		  <vxe-table-column width="34" title="拖动">
		    <template v-slot>
		      <span class="drag-btn">
		        <i class="vxe-icon--menu"></i>
		      </span>
		    </template>
		    <template v-slot:header>
		      <el-tooltip
		        class="item"
		        effect="dark"
		        content="按住后可以上下拖动排序"
		        placement="top-start"
		      >
		        <i class="vxe-icon--question"></i>
		      </el-tooltip>
		    </template>
		  </vxe-table-column>
		  <vxe-table-column
		    field="fieldDesc"
		    width="200"
		    title="字段名称"
		  ></vxe-table-column>
		  <vxe-table-column
		    field="showName"
		    width="140"
		    title="字段说明"
		    :edit-render="{ name: 'input', type: 'visible' }"
		  ></vxe-table-column>
		  <vxe-table-column
		    field="query"
		    width="180"
		    title="是否用于一张图弹窗显示"
		  >
		    <template v-slot="{ row }">
		      <vxe-checkbox v-model="row.isShowMap"></vxe-checkbox>
		    </template>
		  </vxe-table-column>
		  <vxe-table-column field="list" width="150" title="是否用于表格筛选">
		    <template v-slot="{ row }">
		      <vxe-checkbox v-model="row.isShowHeader"></vxe-checkbox>
		    </template>
		  </vxe-table-column>
		</vxe-table>
		<div class="footer" style="text-align: right;margin-top:20px;">
		  <el-button type="primary" @click="submitHandelConfirm"
		    >保存</el-button
		  >
		  <el-button @click="addVisible = false">返回</el-button>
		</div>
	</el-dialog>
</template>

export default {
	data() {
		addVisible: false,
		watchList: [], // 表格数据
		dataForm: {
			id: '',
		}
	},
	methods: {
		init(id) {
			this.addVisible = true
			this.$nextTick(() => {
				this.rowDrop()
			})
		},
		// 表格拖动逻辑
		rowDrop() {
		  this.$nextTick(() => {
		    const xTable = this.$refs.xTable
		    this.sortable1 = Sortable.create(
		      xTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'),
		      {
		        handle: '.drag-btn',
		        onEnd: ({ newIndex, oldIndex }) => {
		          const currRow = this.watchList.splice(oldIndex, 1)[0]
		          this.watchList.splice(newIndex, 0, currRow)
		        }
		      }
		    )
		  })
		},
		// 保存
	    submitHandelConfirm: debounce(function() {
	      this.$http.post('/pipenetwork/device/savePopupInfo', {
            deviceId: this.watchID,
            popupInfos: this.watchList, // 提交的表格数据
          }).then(res => {
            res = res.data
            if (res.code == 500) return this.$message.error(res.msg)
            this.$message.success('保存成功')
          }).catch(() => {})
      	}, 1000, { leading: true, trailing: false }),
	}
}

接下来我们在父组件中调用

<template>
	<div class="site-manage">
		<el-table
	      :data="tableData"
	      style="width: 100%">
	      <el-table-column
	        prop="date"
	        label="日期"
	        width="180">
	      </el-table-column>
	      <el-table-column
	        prop="name"
	        label="姓名"
	        width="180">
	      </el-table-column>
	      <el-table-column
	        prop="address"
	        label="地址">
	      </el-table-column>
	      <el-table-column :label="$t('handle')" fixed='right' align='center'>
	          <template slot-scope='scope'>
	            <el-button v-if="$hasPermission('sys:user:update')" type='text' size='small' @click='addOrUpdateHandle(scope.row.id)'>{{ $t('update') }}</el-button>
	          </template>
	        </el-table-column>
	    </el-table>
		<AddOrUpdate v-if='addOrUpdateVisible' ref="addOrUpdatePipe" @refreshDataList="getDataList"></AddOrUpdate>
	</div>
</template>

<script>
	import AddOrUpdate from './device-child-components/device-add-update'
	
	export default {
		data() {
			return {
				tableData: [],
				addOrUpdateVisible: false,
			}
		},
		created() {},
		methods: {
			// 新增
			addOrUpdateHandle(id) {
				this.addOrUpdateVisible = true // 显示弹窗
				this.$nextTick(() => {
					this.$refs['addOrUpdatePipe'].init() // 调用子组件的init方法
          			this.$refs['addOrUpdatePipe'].dataForm.id = id
				})
			}
		}
	}
</script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值