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}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值