elTable实现树形结构拖拽功能
当别人问你vue的编译过程是怎么样的时候,你怎样回答?我们先说什么是编译,为什么要编译,首先因为vue写的html模板,是浏览器识别不了的,我们通过编译的过程,可以进行依赖收集,进行依赖收集之后我们就把Data中的数据模型和视图之间产生依赖关系,当模型发生变化的时候,我们就可以通知这些依赖的地方让他们进行更新,这就是我们执行编译的目的,我们把这些界面全部编译以后,更新操作,我们就可以做到模型驱动视
·
问题描述:当一个表格,有很多层嵌套数据时,想实现拖拽改变顺序
使用方法:sortablejs
第一步:安装sortablejs
npm install sortablejs --save
第二步:在需要的地方引入
import Sortable from 'sortablejs'
第三步:准备需要的表格
<template>
<div>
<el-table ref="dragTable" row-key="id" :data="treeTableData" :expand-row-keys="treeTableExpandKeys" border @expand-change="treeTableExpandChange">
<el-table-column prop="name" label="名字"></el-table-column>
<el-table-column prop="age" label="年龄"></el-table-column>
<el-table-column prop="desc" label="描述"></el-table-column>
</el-table>
</div>
</template>
第四步:data定义数据
data() {
return {
treeTableData: [
{
id: '1',
name: '张三',
age: 11,
desc: '法外狂徒',
children: [
{
id: '2',
name: '月尊大人',
age: 15,
desc: '小兰花',
children: [
{
id: '6',
name: '仓盐海',
age: 15,
desc: '云梦泽'
}
]
}
]
},
{
id: '3',
name: '凌不疑',
age: 18,
desc: '三三',
children: [
{
id: '4',
name: '四四',
age: 25,
desc: '五五'
},
{
id: '5',
name: '不知道叫什么了',
age: 26,
desc: '哈哈哈'
}
]
}
],
flatTreeData: [],
treeTableExpandKeys: [],
sortableObj: null
}
}
初始化
mounted(){
this.transverseNode(this.treeTableData, 1, (node, level, parentNode) => {
node.level = level
node.parentId = parentNode ? parentNode.id : -1
})
his.initSortable()
this.getFlatNode(this.treeTableData, this.flatTreeData)
}
方法
beforeDestroy() {
if (this.sortableObj) {
this.sortableObj.destroy()
}
},
methods: {
initSortable() {
// 获取容器元素
const el = this.$refs.dragTable.$el.querySelectorAll('.el-table__body-wrapper > table > tbody')[0]
if (!el) return
this.sortableObj = new Sortable(el, {
group: 'dragName',
draggable: '.el-table__row',
onEnd: evt => {
const { newIndex, oldIndex } = evt
const dragRow = this.flatTreeData[oldIndex]
const relatedRow = this.flatTreeData[newIndex]
if (dragRow.parentId !== relatedRow.parentId) {
this.$message.warning('只能同层级内排序')
this.reRender(null, 'treeTableData')
} else {
// 都无children
if (!dragRow.children && !relatedRow.children) {
const oldData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex, 0, oldData)
}
// drag有, relate无
if (dragRow.children && !relatedRow.children) {
const oldData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex, 0, oldData)
if (newIndex < oldIndex) {
// 有子元素的,子元素需要同样跟上来
const flatChildren = []
this.getFlatNode(oldData.children || [], flatChildren)
if (flatChildren.length > 0) {
for (let i = 1, len = flatChildren.length; i <= len; i++) {
const childData = this.flatTreeData.splice(oldIndex + i, 1)[0]
this.flatTreeData.splice(newIndex + i, 0, childData)
}
}
} else {
// 有子元素的,子元素需要同样跟下来
const flatChildren = []
this.getFlatNode(oldData.children || [], flatChildren)
if (flatChildren.length > 0) {
for (let i = 1, len = flatChildren.length; i <= len; i++) {
const childData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex, 0, childData)
}
}
}
}
// drag无, relate有
if (!dragRow.children && relatedRow.children) {
const oldData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex, 0, oldData)
if (newIndex > oldIndex) {
// 有子元素的,子元素需要同样跟上来
const flatChildren = []
this.getFlatNode(relatedRow.children || [], flatChildren)
if (flatChildren.length > 0) {
for (let i = 1, len = flatChildren.length; i <= len; i++) {
const childData = this.flatTreeData.splice(newIndex + i, 1)[0]
this.flatTreeData.splice(newIndex + i - 1, 0, childData)
}
}
}
}
// drag有, relate有
if (dragRow.children && relatedRow.children) {
if (newIndex < oldIndex) {
const oldData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex, 0, oldData)
// 有子元素的,子元素需要同样跟上来
const flatChildren = []
this.getFlatNode(oldData.children || [], flatChildren)
if (flatChildren.length > 0) {
for (let i = 1, len = flatChildren.length; i <= len; i++) {
const childData = this.flatTreeData.splice(oldIndex + i, 1)[0]
this.flatTreeData.splice(newIndex + i, 0, childData)
}
}
} else {
const oldData = this.flatTreeData.splice(oldIndex, 1)[0]
// relateRow的children数
const relateFlatChildren = []
this.getFlatNode(relatedRow.children || [], relateFlatChildren)
this.flatTreeData.splice(newIndex + relateFlatChildren.length, 0, oldData)
// 有子元素的,子元素需要同样跟下来
const flatChildren = []
this.getFlatNode(oldData.children || [], flatChildren)
if (flatChildren.length > 0) {
for (let i = 1, len = flatChildren.length; i <= len; i++) {
const childData = this.flatTreeData.splice(oldIndex, 1)[0]
this.flatTreeData.splice(newIndex + relateFlatChildren.length, 0, childData)
}
}
}
}
// 重新生成树的数据
const data = this.getTreeData(this.flatTreeData, [])
console.log('this.flatTreeData', this.flatTreeData, data)
// 页面重新渲染
this.reRender(data, 'treeTableData')
}
}
})
},
getFlatNode(nodes, flatList, childrenKey = 'children') {
nodes.forEach(node => {
flatList.push(node)
if (node[childrenKey] && node[childrenKey].length) {
this.getFlatNode(node[childrenKey], flatList)
}
})
},
getTreeData(nodes, resultList) {
const childStack = []
let lastNode = {}
nodes.forEach(node => {
delete node.children
const pushNode = dataNode => {
const parentNode = childStack[childStack.length - 1]
if (parentNode) {
parentNode.children.push(dataNode)
} else {
resultList.push(dataNode)
}
}
if (node.level < lastNode.level) {
childStack.length = node.level - 1
pushNode(node)
} else if (node.level === lastNode.level) {
pushNode(node)
} else if (node.level > lastNode.level) {
if (!lastNode.children) {
lastNode.children = []
}
childStack.push(lastNode)
pushNode(node)
} else {
resultList.push(node)
}
lastNode = node
})
return resultList
},
reRender(data, dataKey) {
if (data) {
this[dataKey] = []
this.$nextTick(() => {
this[dataKey] = data
})
} else {
const origin = [].concat(this[dataKey])
this[dataKey] = []
this.$nextTick(() => {
this[dataKey] = origin
})
}
},
transverseNode(nodes, level = 1, cb, parentNode, childKey = 'children') {
nodes.forEach(node => {
if (node[childKey] && node[childKey].length > 0) {
this.transverseNode(node[childKey], level + 1, cb, node, childKey)
}
cb(node, level, parentNode)
})
return nodes
},
treeTableExpandChange(row, expanded) {
if (expanded) {
this.treeTableExpandKeys.push(row.id)
} else {
const idx = this.treeTableExpandKeys.indexOf(row.id)
this.treeTableExpandKeys.splice(idx, 1)
}
}
}
更多推荐
已为社区贡献4条内容
所有评论(0)