<template> <div class="container"> <div class="options" v-for="(item, index) in data.bottomOptionsList" :key="item.title" @click="fnBottomOptionsListChange(item, index)" > <div class="option"> <img :src="item.check ? item.imgSelect : item.img" alt="" /> <div class="title">{{ item.title }}</div> </div> <div :class="['child_container', { active: item.check }]"> <div :class="['child_options', item.type]"> <div class="child_option" v-for="(item1, index1) in item.list" :key="item1.title" @click.stop="fnBottomChildOptionsListChange(index, item1, index1)" > <img :src="item1.check ? item1.imgSelect : item1.img" alt="" /> <div class="tit" :class="item1.check ? 'active' : ''"> {{ item1.title }} </div> </div> </div> </div> </div> </div> </template> <script setup> import { reactive, markRaw } from "vue"; import Personnel from "@/views/BI/components/personnel.vue"; import WorkSafely from "@/views/BI/components/work_safely.vue"; import EntranceControl from "@/views/BI/components/entrance_control.vue"; import GraveDangerous from "@/views/BI/components/grave_dangerous.vue"; import VideoAIAnalysis from "@/views/BI/components/video_ai_analysis.vue"; import VideoAIAnalysisRight from "@/views/BI/components/video_ai_analysisRight.vue"; import { useVModels } from "@vueuse/core"; import { handleTrajectory, handleFence } from "@/views/BI/js/trajectory.js"; import { handleHortwork, handleConfinedspaceWork, handleHighWork, } from "@/views/BI/js/eight_work.js"; import { handleCamera } from "@/views/BI/js/camera.js"; const props = defineProps({ leftCurrentComponent: { type: [Object, Function, String], required: true, default: "", }, rightCurrentComponent: { type: [Object, Function, String], required: true, default: "", }, rightOption: { type: Boolean, required: true, default: false, }, }); const emits = defineEmits([ "update:leftCurrentComponent", "update:rightCurrentComponent", "update:rightOption", ]); const { leftCurrentComponent, rightCurrentComponent, rightOption } = useVModels( props, emits ); const bottomOptionsList = [ { img: new URL("/src/assets/images/map/bico1.png", import.meta.url).href, imgSelect: new URL("/src/assets/images/map/bico1_on.png", import.meta.url) .href, title: "人员定位", type: "personnelPositioning", check: false, components: [markRaw(Personnel)], list: [ { img: new URL("/src/assets/images/map/bottom/ico1.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico1_on.png", import.meta.url ).href, title: "人员", type: "personnel", check: false, action: handleTrajectory, }, { img: new URL("/src/assets/images/map/bottom/ico2.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico2_on.png", import.meta.url ).href, title: "视频", type: "video", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico3.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico3_on.png", import.meta.url ).href, title: "电子围栏", type: "electronicFence", check: false, action: handleFence, }, ], }, { img: new URL("/src/assets/images/map/bico2.png", import.meta.url).href, imgSelect: new URL("/src/assets/images/map/bico2_on.png", import.meta.url) .href, title: "安全作业", type: "workSafely", check: false, components: [markRaw(WorkSafely)], list: [ { img: new URL("/src/assets/images/map/bottom/ico4.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico4_on.png", import.meta.url ).href, title: "动火作业", type: "hotWork", check: false, action: handleHortwork, }, { img: new URL("/src/assets/images/map/bottom/ico5.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico5_on.png", import.meta.url ).href, title: "受限空间作业", type: "acceptance", check: false, action: handleConfinedspaceWork, }, { img: new URL("/src/assets/images/map/bottom/ico6.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico6_on.png", import.meta.url ).href, title: "临时用电作业", type: "temporaryElectricalWork", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico7.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico7_on.png", import.meta.url ).href, title: "高处作业", type: "workAtHeight", check: false, action: handleHighWork, }, { img: new URL("/src/assets/images/map/bottom/ico8.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico8_on.png", import.meta.url ).href, title: "断路作业", type: "circuitBreakingOperations", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico9.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico9_on.png", import.meta.url ).href, title: "动土作业", type: "groundbreakingWork", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico10.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico10_on.png", import.meta.url ).href, title: "吊装作业", type: "hoistingOperations", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico11.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico11_on.png", import.meta.url ).href, title: "盲板抽堵作业", type: "blindPlatePluggingOperation", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico12.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico12_on.png", import.meta.url ).href, title: "摄像头", type: "workSafelyCamera", check: false, action: handleCamera, }, ], }, { img: new URL("/src/assets/images/map/bico3.png", import.meta.url).href, imgSelect: new URL("/src/assets/images/map/bico3_on.png", import.meta.url) .href, title: "口门门禁", type: "entranceControl", check: false, components: [markRaw(EntranceControl)], list: [ { img: new URL("/src/assets/images/map/bottom/ico13.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico13_on.png", import.meta.url ).href, title: "人员", type: "personnel", check: false, // action: }, { img: new URL("/src/assets/images/map/bottom/ico14.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico14_on.png", import.meta.url ).href, title: "车辆", type: "vehicle", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico15.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico15_on.png", import.meta.url ).href, title: "摄像头", type: "camera", check: false, }, ], }, { img: new URL("/src/assets/images/map/bico4.png", import.meta.url).href, imgSelect: new URL("/src/assets/images/map/bico4_on.png", import.meta.url) .href, title: "重大危险源", type: "significantSourcesOfDanger", check: false, components: [markRaw(GraveDangerous)], list: [ { img: new URL("/src/assets/images/map/bottom/ico16.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico16_on.png", import.meta.url ).href, title: "储罐区", type: "tankFarms", check: false, }, { img: new URL("/src/assets/images/map/bottom/ico17.png", import.meta.url) .href, imgSelect: new URL( "/src/assets/images/map/bottom/ico17_on.png", import.meta.url ).href, title: "压力管道", type: "pressurePiping", check: false, }, ], }, { img: new URL("/src/assets/images/map/bico5.png", import.meta.url).href, imgSelect: new URL("/src/assets/images/map/bico5_on.png", import.meta.url) .href, title: "视频AI分析", type: "videoAIAnalysis", check: false, components: [markRaw(VideoAIAnalysis), markRaw(VideoAIAnalysisRight)], action: handleCamera, }, ]; const data = reactive({ bottomOptionsList, }); const fnBottomOptionsListChange = (item, index) => { // ai 视频报警 if (index === 4) { data.bottomOptionsList[index].action( !data.bottomOptionsList[index].check, item.type ); } for (let i = 0; i < data.bottomOptionsList.length; i++) { if (index === i) { data.bottomOptionsList[index].check = !data.bottomOptionsList[index].check; continue; } data.bottomOptionsList[i].check = false; } leftCurrentComponent.value = data.bottomOptionsList[index].check ? item.components[0] : ""; rightCurrentComponent.value = data.bottomOptionsList[index].check ? item.components[1] : ""; rightOption.value = index !== 4; }; const fnBottomChildOptionsListChange = (index, item1, index1) => { data.bottomOptionsList[index].list[index1].check = !data.bottomOptionsList[index].list[index1].check; data.bottomOptionsList[index].list[index1].action( data.bottomOptionsList[index].list[index1].check, item1.type ); }; </script> <style scoped lang="scss"> .container { width: 100%; position: relative; .options { width: 80px; height: 95px; position: absolute; text-align: center; cursor: pointer; &:nth-child(1) { left: 130px; bottom: -54px; } &:nth-child(2) { left: 280px; bottom: -34px; } &:nth-child(3) { left: 430px; bottom: -25px; } &:nth-child(4) { left: 580px; bottom: -34px; } &:nth-child(5) { left: 730px; bottom: -54px; } .title { margin-top: 5px; font-size: 14px; } .child_container { position: relative; width: 80px; height: 95px; left: 0; top: -95px; display: none; &.active { display: block; } .child_options { position: absolute; left: 50%; top: -120px; transform: translateX(-50%); background-image: linear-gradient( to right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.4) 50%, rgba(0, 0, 0, 0) 100% ); border: 1px solid; border-image: linear-gradient( to right, rgba(0, 0, 0, 0) 0%, rgba(2, 119, 142, 1) 50%, rgba(255, 255, 255, 0) 100% ) 1; border-left: none; border-right: none; display: flex; animation: 0.5s all; .child_option { text-align: center; display: inline-block; padding: 15px 25px; .tit { white-space: nowrap; } .active { color: #28b9fe; } } &.workSafely { left: 100%; } } } } } </style>