欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

element-ui 树形表格 懒加载 手风琴模式 拖动排序

程序员文章站 2022-03-21 19:30:06
手风琴模式实现的效果: 其中一个节点展开时,其他节点关闭,一直保持最多只有一个节点是展开的。需要解决的问题: element-ui 树形懒加载表格自带的节点展开时,默认只有第一次才会触发load函数,之后在重新展开节点时,并不会触发load函数。实现原理:同一个的节点多次重复操作展开子节点时只触发一次load加载函数。当一个节点的子节点展开时,其他节点的子节点收起,同时新展开的节点都需要触发load函数手风琴模式: 根据element-ui文档创建树形表格row-key : 用来优化 Table...

手风琴模式

实现的效果: 其中一个节点展开时,其他节点关闭,一直保持最多只有一个节点是展开的。

需要解决的问题: element-ui 树形懒加载表格自带的节点展开时,默认只有第一次才会触发load函数,之后在重新展开节点时,并不会触发load函数。

实现原理:同一个的节点多次重复操作展开子节点时只触发一次load加载函数。当一个节点的子节点展开时,其他节点的子节点收起,同时新展开的节点都需要触发load函数

手风琴模式: 根据element-ui文档创建树形表格
row-key : 用来优化 Table 的渲染;在使用 reserve-selection 功能与显示树形数据时,该属性是必填的
lazy : 开启懒加载模式
tree-props :指定哪些行是包含子节点
load :绑定节点加载函数

<template>
	<el-table ref="multipleTable" :data="list" row-key="id" lazy :load="load" :tree-props="{children: 'children', hasChildren: 'hasChildren'}"></el-table>
</template>
<script>
	import { listCategoryfrom } form  '@/api/category'
	export default {
		data() {
			return {
				listQuery: {
					page: 1,
					limit: 10
				},
				list: []
			}
		},
		methods: {
			load(tree, treeNode, resolve) {
		        const newListQuery = JSON.parse(JSON.stringify(this.listQuery))
		        newListQuery.cid = tree.id
		        // 动态加载子节点数据
		        listCategory(newListQuery).then(response => {
		          this.$nextTick(function() {
		            this.list.map(item => {
		              if (item.id != tree.id) {
		                // 使用手风琴模式 expanded 控制子节点关闭还是开启,loaded设置为false,可以使树形表格每次都能加载
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'loading', false)
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'loaded', false)
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'expanded', false)
		              }
		            })
		          })
		          resolve(response.data.data.items)
		        })
		     },
		}
	}
</script>

需要显示为手风琴模式,重点的代码是 this.$nextTick() 中的函数

this.$refs.multipleTable.store.states.treeData 获取所有父节点的状态

重新设置加载状态(这里是加载防止异常所以设置)
this.set(this.set(this.refs.multipleTable.store.states.treeData[item.id], ‘loading’, false)

重新设置节点未加载(手风琴重点代码,使load函数能够多次触发,解决了load不能多次触发的问题)
this.set(this.set(this.refs.multipleTable.store.states.treeData[item.id], ‘loaded’, false)

关闭已经打开的子节点 (expanded 为true 表示子节点展开, false 表示子节点关闭)
this.set(this.set(this.refs.multipleTable.store.states.treeData[item.id], ‘expanded’, false)

手风琴模式下的表格拖动排序

安装拖动插件 sortablejs
npm install sortablejs --save
在页面中引入
import Sortable from ‘sortablejs’

<template>
	<el-table ref="multipleTable" :data="list" row-key="id" lazy :load="load" :tree-props="{children: 'children', hasChildren: 'hasChildren'}"></el-table>
</template>
<script>
	import Sortable from 'sortablejs'
	import { listCategoryfrom } form  '@/api/category'
	export default {
		data() {
			return {
				listQuery: {
					page: 1,
					limit: 10
				},
				list: [],
				treeDate: {
	          		children: [],
	        		display: true,
	        		expanded: false,
	       		    lazy: true,
	       		    level: 0,
	      		    loaded: false,
	      		    loading: false
	     	   }
			}
		},
		mounted() {
    		  // 表格拖拽
  		   document.body.ondrop = function(event) {
     		   event.preventDefault();
    		   event.stopPropagation();
   		   }
     	   this.rowDrop()
  		},
		methods: {
			load(tree, treeNode, resolve) {
		        const newListQuery = JSON.parse(JSON.stringify(this.listQuery))
		        newListQuery.cid = tree.id
		        // 动态加载子节点数据
		        listCategory(newListQuery).then(response => {
		          this.$nextTick(function() {
		            this.list.map(item => {
		              if (item.id != tree.id) {
		                // 使用手风琴模式 expanded 控制子节点关闭还是开启,loaded设置为false,可以使树形表格每次都能加载
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'loading', false)
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'loaded', false)
		                this.$set(this.$refs.multipleTable.store.states.treeData[item.id], 'expanded', false)
		              }
		            })
		          })
		          resolve(response.data.data.items)
		        })
		     },
		     rowDrop() {
		     	// 获取表格节点
    		    const tbody = document.querySelector('.el-table__body-wrapper tbody')
     		    const _this = this
     		    // 插件调用函数
     		    Sortable.create(tbody, {
     		    	 // 拖拽开始时
       		   		 onStart({
         			   oldIndex
         		 	 }) {
          		  		 _this.list.forEach(item => {
          		 		 // 重新设置 treeData 的值,让表格行拖动的过程方向图标不会消失(由于重新渲染表格数据,这一行看个人需求是否添加)
             	 		 _this.$set(_this.$refs.multipleTable.store.states.treeData, item.id, _this.treeDate)
             	 		 // 置空子节点数据,保证拖拽时只计算一级节点的数量,否则会造成节点拖拽无法正确计算位置。 lazyTreeNodeMap 是存放子节点的数据
            	 		 _this.$set(_this.$refs.multipleTable.store.states.lazyTreeNodeMap, item.id, [])
          	  		  })
        		  },
        		  // 拖拽结束
         		  onEnd({
         		   newIndex, 
         		   oldIndex
         		  }) {
         		  	  // newIndex表格数据拖动后数据角标   oldIndex表格数据拖动前数据角标
           			  let from, end
          			  from = _this.list[oldIndex].id
        		      end = _this.list[newIndex].id
           			  // console.log(from, end)
           			  // 排序成功后重新获取数据 _this.list = [] 置空数据强制刷新数据,否则子节点数据无法更新,同时会出现bug ,使子节点出现在原来的位置
           			  // 后台排序,排序成功,重置数据
           			  paixu().then(res => {
           			    _this.list = []
           			    // 重新请求数据渲染
         		       _this.getList()
					 })
           			  
       			   }
     		   })
   		   },
		}
	}
</script>

借鉴文章 https://blog.csdn.net/weixin_39001363/article/details/101547148

本文地址:https://blog.csdn.net/lai260172331/article/details/107356303