来看两张效果图,首先来看保存前的数据
再看保存后的数据
其原理简单来说就是,改变了对象数组的某一项在原数据中所在的位置,比如:将数组下标为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>