1. 程式人生 > 程式設計 >vue穿梭框實現上下移動

vue穿梭框實現上下移動

本文例項為大家分享了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,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,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,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
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。