vue穿梭框实现上下移动


Posted in Vue.js onJanuary 29, 2021

本文实例为大家分享了vue穿梭框实现上下移动的具体代码,供大家参考,具体内容如下

使用elementUI的树形组件 tree组件

vue穿梭框实现上下移动

功能需求:

1、左侧的子节点移动到右侧的表格中
2、右侧选中的内容移动到左侧树中,单一移动和全部移动
3、点击右侧节点实现上下移动

首先会遇到的问题可能是如何实现左侧只让子节点显示checkbox,我这边是根据后端返回了一个参数来判断是否是父节点(其实只要后端给父节点加一个nocheck=true就可以)

// setLeftAgency :封装好的请求接口名称
setLeftAgency(params).then((res) => { // 当返回的code==0时就意味着成功
 if (res.data.code == 0) {
 let { data } = res.data;
 data.forEach((item) => { //遍历返回的数据,如果当这个参数是Item时候就给当前这条数据加上nocheck=true,这样就不会显示checkbox
 if(item.Type!=='Item'){
  item.nocheck=true
 }
 // delete item.children;
 });
 this.parentNodes = data; // 把修改好的数据放在数组中再渲染
 }

左侧树结构,中间的按钮和右侧表格(左侧树结构和表格是封装好的,直接引入)

<div class="leftTree"> // 这里绑定的onCreated是左侧树的初始化函数,parentNodes储存了左侧树的所有数据
 <ztree :setting="setting" @onCreated = 'onCreated' :parentNodes="parentNodes"></ztree>
</div>
<div class="centerBtn">
 <el-button type="danger" plain icon="el-icon-arrow-right" @click="moveTable"></el-button>
 <el-button type="danger" plain icon="el-icon-d-arrow-left" @click="moveTreeAll"></el-button>
 <el-button type="danger" plain icon="el-icon-arrow-left" @click="moveTree"></el-button>
 <el-button type="danger" plain @click="moveUp(index)">上移</el-button>
 <el-button type="danger" plain @click="moveDown(index)">下移</el-button>
</div>

<div class="rightTable">
 <table :data.sync="tableData" // 表格接口返回的数据
  ref="personListSettingPage"
  :loading='vxeLoading'
  v-model="selectGroups" // 绑定右侧table选中项的数组
  id="personListSettingPage"
  :showPagination= 'false'
  :height-full-screen = 'false'
  @sort-change="sortChange"
  @checkbox-change="selectChange" // 右侧选中的单选事件
  @checkbox-all="selectAll" // 右侧选中项的全选事件
  @data-refresh="getTableData()"> // 获取右侧表格数据的函数
  <vxe-table-column type="checkbox" width="60" align="center"></vxe-table-column>
  <table-column field="text" show-overflow="title" title="已选指标" filterType='' >
  </table-column>
 </table>
 </div>

用到的参数

moveDownId:"", //下移时储存的数据
moveUpId:"", //上移时遍历右侧表格数据储存的数据
selectGroups:[], // 用来存放右侧选中的数据
tableData:[], // 请求回来后会把左侧的所有数据存放在此数组中
parentNodes:[], //左侧树的所有数据
treeObj:"",

左侧树初始化和右侧表格复选框选择事件

// 初始化ztree
 onCreated(treeObj){
 this.treeObj = treeObj
 let nodes = this.treeObj.getCheckedNodes(true); 
},
 //复选框事件
 selectChange({ checked, records}) {
 this.selectGroups = records // 把选择的那条数据存储到数组中
 },
 //复选框全选事件
 selectAll({ checked, records }) {
 this.selectGroups = records
 },

上移

moveUp(index){
 if(this.selectGroups.length>0){ // 判断右侧是否有选中的项
 let goOrnot = true
 this.selectGroups.find((seItem)=>{ //遍历右侧tab中选中的项,找到对应的id
  if(seItem.id==this.moveUpId.id){
  this.$message.warning(this.moveUpId.text+"此行没有上移的空间了")
  goOrnot = false
  }
 })
 if(goOrnot){
  this.tableData.forEach((item,index)=>{ // 遍历右侧表格所有数据,
  this.$set(item,'rowIndex',index) //由于受JavaScript的限制,vue.js不能监听对象属性的添加和删除,所以要使用$set或者Object.assign(target, sources),这样试图才会更新
  })
  let flag = true
  this.selectGroups.forEach((val,index2)=>{
  this.tableData.find((itm,ind)=>{
   if(val.id==itm.id){
   if(itm.rowIndex==0){ // 遍历右侧选中数据和所有数据相对比,如果id相同,在判断刚刚添加的rowIndex属性值是多少
    this.$message.warning(itm.text+"此行没有上移的空间了")
    this.moveUpId = itm // 把当前这条数据存起来
    flag = false
    return
   }else{
    if(flag){ // 此时可以对多条数据进行移动了
    let changeItem = JSON.parse(JSON.stringify(this.tableData[itm.rowIndex-1]))
    this.tableData.splice(itm.rowIndex-1,1);
    this.tableData.splice(itm.rowIndex,0,changeItem)
    }
   }
   }
  })
  })
 }
 }else{
 this.$message.warning('请选择要移动的数据')
 }
},

下移

moveDown(index){
 if(this.selectGroups.length>0){
 let goOrnot = true
 this.selectGroups.find((seItem)=>{
  if(seItem.id==this.moveDownId.id){
  this.$message.warning(this.moveDownId.text+"此行没有下移的空间了")
  goOrnot = false
  }else{
  this.moveFlag = true
  }
 })
 if(goOrnot){
  this.tableData.forEach((item,index)=>{
  this.$set(item,'rowIndex',index)
  })
  let selectData = JSON.parse(JSON.stringify(this.tableData))
  let a=[...this.selectGroups]
  a.reverse().forEach((val,index2)=>{
  selectData.find((itm,ind)=>{
   if(val.id==itm.id){
   if(itm.rowIndex==selectData.length-1){
    this.$message.warning(itm.text+"此行没有下移的空间了")
    this.moveDownId = itm
    this.moveFlag = false
   }else{
    if(this.moveFlag){
    let changeItem = itm
    let delIndex=selectData.findIndex(i=>i.id == changeItem.id)
    this.tableData.splice(delIndex,1);
    this.tableData.splice(delIndex+1,0,changeItem)
    this.$refs.personListSettingPage.$refs.Table.setCheckboxRow(this.tableData[itm.rowIndex+1],true) // 给右侧table加了一个ref=personListSettingPage
    }
   }
   }
  })
  })
 }
 }else{
 this.$message.warning('请选择要移动的数据')
 }
}

表格移动到树

/* 移入tree */
moveTree(){
 if(this.selectGroups.length>0){
 this.selectGroups.forEach(item=>{
  this.parentNodes.find(val=>{
  if(val.id == item.pid){
   /* 添加节点 */
   let node = this.treeObj.getNodeByParam("id", val.id, null);
   this.treeObj.addNodes(node,item)
   /* 取消新增节点的选中状态 */
   let cancelNode = this.treeObj.getNodeByParam("id", item.id, null);
   this.treeObj.checkNode(cancelNode,false,true);
  }
  })
  this.tableData.splice(this.tableData.findIndex(val => val.id === item.id), 1)
 })
 }else{
 this.$message.warning('请选择要移动的数据')
 }
},

树移到表格

/* 移入表格 */
moveTable(){
 let arr=[]
 let nodes = this.treeObj.getCheckedNodes(true);
 if(nodes.length>0){
 nodes.forEach(item=>{
  this.tableData.find(val=>{
  arr.push(val.id)
  })
  if(arr.indexOf(item.id)>-1) return this.$message.error("数据重复,请勿重新添加")
  this.treeObj.removeNode(item)
  this.tableData.push(this.filterObj(item,["checked","codeSetId",'id','img','infoItemFlag','isMult','itemType','locked','mult','orgCode','pid','sort','syrs','text'])) // 调用下面的方法,去除多余字段
 })
 }else{
 this.$message.warning('请勾选数据')
 }
},

封装的过滤字段

/* 过滤对象多余字段 */
filterObj(obj, arr) {
 const result = {}
 Object.keys(obj).filter((key) => arr.includes(key)).forEach((key) => {
 result[key] = obj[key]
 })
 return result
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
如何使用 vue-cli 创建模板项目
Nov 19 Vue.js
vue element实现表格合并行数据
Nov 30 Vue.js
Vue 实现一个简单的鼠标拖拽滚动效果插件
Dec 10 Vue.js
vue3中轻松实现switch功能组件的全过程
Jan 07 Vue.js
Vuex实现简单购物车
Jan 10 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
Vue多选列表组件深入详解
Mar 02 Vue.js
vue中data改变后让视图同步更新的方法
Mar 29 Vue.js
解决Vue+SpringBoot+Shiro跨域问题
Jun 09 Vue.js
Vue elementUI表单嵌套表格并对每行进行校验详解
Feb 18 Vue.js
VUE递归树形实现多级列表
Jul 15 Vue.js
vue使用transition组件动画效果的实例代码
Jan 28 #Vue.js
Vue ​v-model相关知识总结
Jan 28 #Vue.js
Vue 数据响应式相关总结
Jan 28 #Vue.js
vue.js实现点击图标放大离开时缩小的代码
Jan 27 #Vue.js
vscode自定义vue模板的实现
Jan 27 #Vue.js
vue+echarts实现中国地图流动效果(步骤详解)
Jan 27 #Vue.js
vue3 watch和watchEffect的使用以及有哪些区别
Jan 26 #Vue.js
You might like
php提示无法加载或mcrypt没有找到 PHP 扩展 mbstring解决办法
2012/03/27 PHP
PHP截取IE浏览器并缩小原图的方法
2016/03/04 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
php批量删除操作代码分享
2017/02/26 PHP
JavaScript Event学习第三章 早期的事件处理程序
2010/02/07 Javascript
基于jquery的让textarea自适应高度的插件
2010/08/03 Javascript
JS生成随机字符串的多种方法
2014/06/10 Javascript
js带点自动图片轮播幻灯片特效代码分享
2015/09/07 Javascript
jQuery弹出层后禁用底部滚动条(移动端关闭回到原位置)
2016/08/29 Javascript
微信小程序 scroll-view隐藏滚动条详解
2017/01/16 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
2018/09/01 Javascript
Javascript 之封装(Package)
2018/09/14 Javascript
jQuery实现的模仿雨滴下落动画效果
2018/12/11 jQuery
微信小程序实现搜索功能
2020/03/10 Javascript
vue实现淘宝购物车功能
2020/04/20 Javascript
vue-router为激活的路由设置样式操作
2020/07/18 Javascript
Python开发微信公众平台的方法详解【基于weixin-knife】
2017/07/08 Python
浅谈Django REST Framework限速
2017/12/12 Python
Python3 XML 获取雅虎天气的实现方法
2018/02/01 Python
python3实现随机数
2018/06/25 Python
Python pymongo模块常用操作分析
2018/09/01 Python
python Pexpect 实现输密码 scp 拷贝的方法
2019/01/03 Python
Python多线程原理与用法实例剖析
2019/01/22 Python
opencv与numpy的图像基本操作
2019/03/08 Python
Django多数据库联用实现方法解析
2020/11/12 Python
python实现xml转json文件的示例代码
2020/12/30 Python
CSS3颜色值RGBA与渐变色使用介绍
2020/03/06 HTML / CSS
《童年》教学反思
2014/02/18 职场文书
市场营销大学生职业规划书
2014/02/25 职场文书
面试必备的求职信
2014/05/25 职场文书
银行领导班子四风对照检查材料
2014/09/27 职场文书
初中家长评语大全
2014/12/26 职场文书
MBA推荐信怎么写
2015/03/25 职场文书
2015年小学语文工作总结
2015/05/25 职场文书
超强台风观后感
2015/06/09 职场文书
MySQL三种方式实现递归查询
2022/04/18 MySQL