先来看看效果
表格拖拽操作
安装Sortable
npm i sortablejs --save
在需要使用的地方引入Sortable
import Sortable from 'sortablejs'
使用方法
首先要给表格加上 row-key="id",因为我这里有三个联动的表格,所以给每个表格加上了唯一id
<el-table
ref="dataTable"
:data="sceneList"
highlight-current-row
border
row-key="id"
id="sence-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '4px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
label="场景名称"
prop="name"
></el-table-column>
<el-table-column width="160" align="center" label="操作">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="detailPord(scope.row)"
>查看产品</el-button
>
</template>
</el-table-column>
</el-table>
<el-table
ref="pordTable"
:data="produceList"
highlight-current-row
border
row-key="id"
id="pord-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '2px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
label="产品名称"
prop="name"
></el-table-column>
<el-table-column align="center" width="280" label="操作">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="showChild(scope.row, 822746444562432, (showTable = 1))"
>功能模块</el-button
>
</template>
</el-table-column>
</el-table>
<el-table
ref="childTable"
:data="moduleList"
highlight-current-row
border
row-key="id"
id="child-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '2px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
:label="
showTable === 1
? '功能模块名称'
: showTable === 2
? '数据目录主题名称'
: '数据服务主题名称'
"
prop="name"
></el-table-column>
<el-table-column align="center" width="280" label="操作">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="handleEditChild(showTable, scope.row)"
>编辑</el-button
>
<el-button
size="mini"
type="text"
@click="handleDeleteChild(showTable, scope.row.id)"
>删除</el-button
>
</template>
</el-table-column>
</el-table>
js部分
写在methods里的方法:
rowDrop() {
let tbody = undefined
if (this.tableType === 1) {
tbody = document.querySelector(
'#sence-tbody .el-table__body-wrapper tbody' // #sence-tbody是表格的id
)
} else if (this.tableType === 2) {
tbody = document.querySelector(
'#pord-tbody .el-table__body-wrapper tbody'
)
} else if(this.tableType === 3){
tbody = document.querySelector(
'#child-tbody .el-table__body-wrapper tbody'
)
}
const that = this
console.log('拿到了咩?', tbody)
Sortable.create(tbody, {
onEnd({ newIndex, oldIndex }) { // 拖拽结束
if (that.tableType === 1) {
const currRow = that.sceneList.splice(oldIndex, 1)[0]
that.sceneList.splice(newIndex, 0, currRow)
console.log('场景', that.sceneList)
let arr = []
that.sceneList.forEach((item, i) => {
arr.push({
id: item.id,
parentId: 0,
orderNum: i
})
})
that.sort(1,arr) // 调用排序接口
} else if (that.tableType === 2) {
const currRow = that.produceList.splice(oldIndex, 1)[0]
that.produceList.splice(newIndex, 0, currRow)
console.log('产品', that.produceList)
let arr = []
that.produceList.forEach((item, i) => {
arr.push({
id: item.id,
parentId: item.parentId,
orderNum: i
})
})
that.sort(1,arr) // 调用排序接口
} else if(that.tableType === 3) {
const currRow = that.moduleList.splice(oldIndex, 1)[0]
that.moduleList.splice(newIndex, 0, currRow)
console.log('模块', that.moduleList)
let arr = []
that.moduleList.forEach((item, i) => {
arr.push({
id: item.id,
menuId: 822746444562432,
productId: item.productId,
orderNum: i
})
})
that.sort(2,arr) // 调用排序接口
}
}
})
},
这里需要注意的是,需要在表格数据加载完成之后再调用this.rowDrop(),否则表格没有创建完成是会报错的,报错如下:
Sortable: `el` must be an HTMLElement, not [object Null]
可以在拿到表格数据后,可以使用 this.$nextTick(() => {})
getScene() {
scene().then((res) => {
// console.log('场景',res.data)
this.sceneList = res.data || []
this.$nextTick(() => {
this.rowDrop()
})
})
},
部分代码
<template>
<div class="source">
<pageHeader :active="6" :bgColor="'#292c4d'"></pageHeader>
<div class="page-content">
<div class="content">
<div class="naver">
<el-button size="small" @click="add(1)">新增场景</el-button>
<!-- <el-button size="small" @click="add(2)">新增产品</el-button> -->
</div>
<el-table
ref="dataTable"
:data="sceneList"
highlight-current-row
border
row-key="id"
id="sence-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '4px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
label="场景名称"
prop="name"
></el-table-column>
<el-table-column width="160" align="center" label="操作">
<template slot-scope="scope">
<el-button size="mini" type="text" @click="detailPord(scope.row)"
>查看产品</el-button
>
</template>
</el-table-column>
</el-table>
</div>
</div>
<pageFooter></pageFooter>
<!-- / 查好看产品 / -->
<el-dialog
title="产品信息"
:visible.sync="dialogPordVisible"
:close-on-click-modal="false"
:before-close="handleClose"
width="80%"
>
<div style="margin-bottom: 8px; display: flex; justify-content: end">
<el-button size="small" @click="add(2)">新增产品</el-button>
</div>
<el-table
ref="pordTable"
:data="produceList"
highlight-current-row
border
row-key="id"
id="pord-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '2px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
label="产品名称"
prop="name"
></el-table-column>
<el-table-column align="center" width="280" label="操作">
<template slot-scope="scope">
<el-button
size="mini"
type="text"
@click="showChild(scope.row, 822746444562432, (showTable = 1))"
>功能模块</el-button
>
</template>
</el-table-column>
</el-table>
</el-dialog>
<!-- / 查看第三级数据 / -->
<el-dialog
:title="
showTable === 1
? '功能模块信息'
: showTable === 2
? '数据目录主题信息'
: '数据服务主题信息'
"
:visible.sync="showTableThird"
:close-on-click-modal="false"
width="80%"
>
<div style="margin-bottom: 8px; display: flex; justify-content: end">
<el-button size="small" @click="addLastChild(showTable)">{{
showTable === 1
? '新增功能模块'
: showTable === 2
? '新增数据目录主题'
: '新增数据服务主题'
}}</el-button>
</div>
<el-table
ref="childTable"
:data="moduleList"
highlight-current-row
border
row-key="id"
id="child-tbody"
style="width: 100%"
:header-cell-style="{
background: '#f0f0f0',
color: '#333',
height: '28px'
}"
:row-style="{ height: '28px' }"
:cell-style="{ padding: '2px' }"
>
<el-table-column
align="center"
type="index"
width="50"
></el-table-column>
<el-table-column
header-align="center"
align="left"
:label="
showTable === 1
? '功能模块名称'
: showTable === 2
? '数据目录主题名称'
: '数据服务主题名称'
"
prop="name"
></el-table-column>
</el-table>
</el-dialog>
</div>
</template>
<script>
import pageHeader from '@/components/pageHeader.vue'
import pageFooter from '@/components/pageFooter.vue'
import {
scene,
product,
saveSceneProd,
updateSceneProd,
delSceneProd,
getDataSubject,
saveDataSubject,
delDataSubject,
updateDataSubject,
sortSceneProd,
sortDataSubject
} from '@/api/sceneProduct' //api接口
import { mapGetters } from 'vuex'
import Sortable from 'sortablejs'
export default {
name: 'SettingPro',
computed: {
// 获取状态管路设置的值
...mapGetters(['isLogin'])
},
data() {
return {
dialogFormVisible: false,
dialogPordVisible: false,
showTableThird: false,
dialogEdit: false,
addOrEditChild: false,
EditChild: false,
showTable: '',
tableType: 1,
productId: 0,
parentId: 0,
show: false,
type: 1,
form: {},
formEdit: {},
childForm: {},
sceneList: [],
produceList: [],
moduleList: [],
}
},
components: { pageHeader, pageFooter },
created() {
this.initData()
},
mounted() {
},
methods: {
rowDrop() {
let tbody = undefined
if (this.tableType === 1) {
tbody = document.querySelector(
'#sence-tbody .el-table__body-wrapper tbody'
)
} else if (this.tableType === 2) {
tbody = document.querySelector(
'#pord-tbody .el-table__body-wrapper tbody'
)
} else if(this.tableType === 3){
tbody = document.querySelector(
'#child-tbody .el-table__body-wrapper tbody'
)
}
const that = this
console.log('87878787', tbody)
Sortable.create(tbody, {
onEnd({ newIndex, oldIndex }) {
if (that.tableType === 1) {
const currRow = that.sceneList.splice(oldIndex, 1)[0]
that.sceneList.splice(newIndex, 0, currRow)
console.log('场景', that.sceneList)
let arr = []
that.sceneList.forEach((item, i) => {
arr.push({
id: item.id,
parentId: 0,
orderNum: i
})
})
that.sort(1,arr)
} else if (that.tableType === 2) {
const currRow = that.produceList.splice(oldIndex, 1)[0]
that.produceList.splice(newIndex, 0, currRow)
console.log('产品', that.produceList)
let arr = []
that.produceList.forEach((item, i) => {
arr.push({
id: item.id,
parentId: item.parentId,
orderNum: i
})
})
that.sort(1,arr)
} else if(that.tableType === 3) {
const currRow = that.moduleList.splice(oldIndex, 1)[0]
that.moduleList.splice(newIndex, 0, currRow)
console.log('模块', that.moduleList)
let arr = []
that.moduleList.forEach((item, i) => {
arr.push({
id: item.id,
menuId: 822746444562432,
productId: item.productId,
orderNum: i
})
})
that.sort(2,arr)
}
}
})
},
// 排序
sort(type, data){
if(type === 1){
sortSceneProd(data).then(res => {
if(res.code === 0){
this.$message({
message: res.msg,
type: 'success'
})
}
})
} else {
sortDataSubject(data).then(res => {
if(res.code === 0){
this.$message({
message: res.msg,
type: 'success'
})
}
})
}
},
// 获取表格数据
getProduceList(parentId) {
product(parentId).then((res) => {
this.produceList = res.data || []
this.$nextTick(() => {
this.rowDrop()
})
})
},
// 获取表格数据
getScene() {
scene().then((res) => {
// console.log('场景',res.data)
this.sceneList = res.data || []
this.$nextTick(() => {
this.rowDrop()
})
})
},
initData() {
this.getScene()
}
}
}
</script>
<style lang="scss" scoped>
</style>