elememt-tree組件實現選擇順序輸出節點並且實現不同父節點之間互斥選擇(含數組差集的實現方法)

elememt-tree組件實現選擇順序輸出節點並且實現不同父節點之間互斥選擇

需求

1.使用element-ui tree組件展現不同類型的機器人的點位信息
2.選擇不同點位信息時會在地圖上畫出不同的線路
3.一次只能選擇一個機器人
4.按照選擇的順序畫出不同的線路的起始點和途徑點

實現

一、實現不同節點的互斥選擇

  1. 保證tree組件的數據的每一個節點和其對應的父節點有相同的id來區分。如下圖
    在這裏插入圖片描述
  2. 使用@check="getCheckedNodes"來判斷每次點擊的節點是否屬於相同的robotId裏,如果不同則清空所有節點,並把當前節點設置爲選中態
getCheckedNodes(data, item) { // 判斷節點是否屬於相同的robotId裏
      if(this.sameFamiliyId !== data.robotId) {
        this.sameFamiliyId = data.robotId
        this.$refs.tree.setCheckedKeys([]) // 清空所有選擇的節點
        this.$refs.tree.setCheckedKeys([data.id]) // 將當前選擇的節點設置爲選中態
      }
    },

二、按照節點選中的順序輸出對應順序的數組
3. 記錄當前節點的選中狀態,雖然element的check-change方法提供了當前節點的狀態返回,但是當你選擇父節點的時候該方法會被多次促發。
4. 把每次選中的節點push到outArray變量中
5. 當點擊父節點的時候,如果父節點是選中的狀態就取outArray和父節點所有子節點的差集,然後把差集push到outArray中去
6. 最後的代碼如下

<template>
  <div>
    <div class="fistPageSlidePic">
      <el-tree
        :data="data"
        show-checkbox
        default-expand-all
        node-key="id"
        ref="tree"
        highlight-current
        @check="getCheckedNodes"
        @check-change = "ischecked"
        :props="defaultProps">
      </el-tree>
    </div>
  </div>
</template>
<script>
import feedBack from './components/feedBack'
export default {
  name: "fistPage",
  components: {feedBack},
  data() {
    return {
      outArray: [],
      checkedflag: false,
      sameFamiliyId: '',
      data: [
          {
            id: 1,
            label: '物流機器人',
            robotId: "wuliuRobot",
            children: [
              {
                id: 2,
                location: [114.0076, 24.890],
                label: '大門口1',
                robotId: "wuliuRobot",
              },
              {
                id: 3,
                location: [114.000, 24.000],
                label: '大門口2',
                robotId: "wuliuRobot",
              },
              {
                id: 4,
                location: [114.1111, 24.1111],
                label: '大門口1',
                robotId: "wuliuRobot",
              },
            ]
          }, 
          {
            id: 5,
            label: '掃地機器人',
            robotId: "saodiRobot",
            children: [
              {
                id: 6,
                location: [114.6666, 24.6666],
                label: '大門口6',
                robotId: "saodiRobot",
              },
              {
                id: 7,
                location: [114.7777, 24.7777],
                label: '大門口2',
                robotId: "saodiRobot",
              },
              {
                id: 8,
                location: [114.8888, 24.8888],
                label: '大門口1',
                robotId: "saodiRobot",
              },
            ]
          }, 
        ],
        defaultProps: {
          children: 'children',
          label: 'label'
        }
    };
  },
  methods: {
    ischecked(data, checked, node) {
      this.checkedflag = checked // 判斷當前節點是否被選中
      console.log('this.checkedflag', this.checkedflag, data)
    },
    getCheckedNodes(data, item) {
      if(this.checkedflag) {
        if(data.children) {
          const diffArray = this.diff(this.outArray, data.children)
          this.outArray.push(...diffArray)
        }else{
          this.outArray.push(data)
        }
      }else{
        if(data.children) {
          this.outArray = []
        }else{
          const tempIndex = this.outArray.findIndex((item)=>{
            return item.id === data.id
          })
          this.outArray.splice(tempIndex,1)
        }
      }
      if(this.sameFamiliyId !== data.robotId) {
        this.sameFamiliyId = data.robotId
        this.$refs.tree.setCheckedKeys([]) // 清空所有選擇的節點
        this.outArray = [] // 清空輸出數組
        if(data.children) {
          this.outArray.push(data.children)
        }else{
          this.outArray.push(data)
        }
        this.$refs.tree.setCheckedKeys([data.id]) // 將當前選擇的節點設置爲選中態
      }
      console.log('最後輸出的數組', this.outArray)
    },
    // 數組的差集
    diff(fistArray, secondArray) {
      const fistArrayIds = fistArray.map((item)=>{
        return item.id
      })
      const secondArrayIds = secondArray.map((item)=>{
        return item.id
      })
      const tempSecond = secondArray.filter((item)=>{
        return !fistArrayIds.includes(item.id)
      })
      const tempFist = fistArray.filter((item)=>{
        return !secondArrayIds.includes(item.id)
      })
      const resultArray = [...tempFist, ...tempSecond]
      console.log('差值數組', resultArray)
      return resultArray
    }
  },
};
</script>
<style lang="less" scoped>
.fistPageSlidePic,
.aboutUs {
  height: 700px;
  width: 100%;
  // border: 1px solid red;
}
.fixbar {
  // color: red;
  position: fixed;
  top: 50vh;
  right: 50px;
  z-index: 100;
}
</style>

三、使用lodash提供的api實現求對象數組的差集
先需要了解lodash的幾個關於數組的api
1.求數組的並集 _.union
2.求數組的交集 _.intersection
3.求數組的補集 _.xor
4.數組去重複 _.uniqWith
總之:在並集中求交集的補集就是差集

diffrentArray(fistArray, secondArray) {
      const fistIds = fistArray.map((item)=>{
        return item.id
      })
      const secondIds = secondArray.map((item)=>{
        return item.id
      })
      const unionTemp = _.union(fistIds, secondIds) // 求數組的並集
      const interTemp = _.intersection(fistIds, secondIds) // 求數組的交集
      const xorTemp = _.xor(unionTemp, interTemp) // 在並集中求交集的補集就是差集
      const totalArray = _.uniqWith([...fistArray, ...secondArray], _.isEqual)// 數組合並並且去重
      const result =  totalArray.filter((item)=>{
        return xorTemp.includes(item.id)
      })
      console.log('數組差集  result', result)
    }

四、使用Es6的api實現求對象數組的差集

// 數組的差集
    diff(fistArray, secondArray) {
      const fistArrayIds = fistArray.map((item)=>{
        return item.id
      })
      const secondArrayIds = secondArray.map((item)=>{
        return item.id
      })
      const tempSecond = secondArray.filter((item)=>{
        return !fistArrayIds.includes(item.id)
      })
      const tempFist = fistArray.filter((item)=>{
        return !secondArrayIds.includes(item.id)
      })
      const resultArray = [...tempFist, ...tempSecond]
      console.log('差值數組', resultArray)
      return resultArray
    }

補:用loadas加reduce實現數組的差集(支持多個數組)

   diffArray1(...args) {
     let total = args[0]
     const xorTemp = args.reduce((pre, curren)=>{
       total = _.uniqWith([...total, ...curren], _.isEqual) // 數組合並並且去重
       return _.intersection(pre, curren) // 求數組的交集
     })
     return _.xor(total, xorTemp) // 在並集中求交集的補集就是差集
   }

reduce函數的使用:

  1. 該函數會循環數組的每一項去執行一個函數,並且把執行的結果返回
  2. 該函數可以設置初始值,更神奇的是初始值的類型可以自定義。
    舉個栗子(統計個字符串中的字母出現的次數),大家好好感受:
    totalTitle(title) {
      var res =  title.split('').reduce((pre, curren)=>{
        pre[curren]? pre[curren]++ : pre[curren] = 1
        return pre
      },{})
      console.log('res======>', res)
    }
    totalTitle('sssssdfdfdfdf') // ===> {s: 5, d: 4, f: 4}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章