需求
1.使用element-ui tree組件展現不同類型的機器人的點位信息
2.選擇不同點位信息時會在地圖上畫出不同的線路
3.一次只能選擇一個機器人
4.按照選擇的順序畫出不同的線路的起始點和途徑點
實現
一、實現不同節點的互斥選擇
- 保證tree組件的數據的每一個節點和其對應的父節點有相同的id來區分。如下圖
- 使用@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函數的使用:
- 該函數會循環數組的每一項去執行一個函數,並且把執行的結果返回
- 該函數可以設置初始值,更神奇的是初始值的類型可以自定義。
舉個栗子(統計個字符串中的字母出現的次數),大家好好感受:
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}