需求:此篇文章的需求背景是有一条H线,H线上有4个H点,每个H点有4张图片,当点击某个H点的某张图片时,打开该弹窗,并进行切换,当前H点切换结束后根据向左或向右切换进行自动拼接前一H点或后一H点内容,自动组成下方图片列表内容
开发:开发内容是一个弹窗,此弹窗是在父级页面选中了某一相册下的某一张图片后弹出
功能:向左切换,向右切换,点击下方图片列表的图片(以下相册=H点,H点=相册),显示或隐藏下方图片列表
功能详解:
1.多个相册可进行无缝衔接式切换,下方展示相册列表,上方显示图片时下方相册列表进行联动,下方相册列表中对应的图片展示白色边框
2.选中点击下方相册列表中的图片时上方图片随之展示当前选中的图片
3.可进行左右切换,当切换到第一张或最后一张时进行提示
4.每个相册默认4张图片,当当前相册已切换完后,下方相册列表自动拼接,当点击向左切换时下方相册列表为该相册本身与上一相册内容,同理,当点击向右切换时下方相册列表为该相册本身与下一相册内容
5.显示或隐藏下方图片列表
6.使用的都是假数据,如果大家有类似需要,可以根据自己需求进行修改切换时的坐标计算方式,图片路径记得改哦
代码:
html部分:
<template>
<div class="pointImgDialog" v-show="imgSwitchDialog">
<div class="pointAll">
<div class="pointAll_top">
<div class="ptTop" @click="emit('closeImgSwitchDialog')">
<span class="iconfont icon-guanbi"/>
</div>
<div class="ptBot">
<div class="ptBot_left">
<div class="icon" @click="leftSwitch">
<span class="iconfont icon-xiangzuo1 iconStyle"/>
</div>
</div>
<div class="ptBot_cen">
<img :src="state.largeImg" class="cenImg">
<div class="cenNamePosition">{{state.pName}}</div>
</div>
<div class="ptBot_right">
<div class="icon" @click="rightSwitch">
<span class="iconfont icon-xiangyou iconStyle"/>
</div>
</div>
</div>
</div>
<div class="pointAll_bot" :style="state.imgListShow?'height:18%':'height:3%'">
<div class="pbTop">
<div class="pbTop_icon" @click="state.imgListShow=!state.imgListShow">
<span class="iconfont icon-icon_on_the_down" v-show="state.imgListShow"/>
<span class="iconfont icon-icon_on_the_top" v-show="!state.imgListShow"/>
</div>
</div>
<div class="pbBot" v-show="state.imgListShow">
<div v-for="(item,index) in state.pointImgList" :key="index" class="pbBotItem" @click="chooseImg(item,index)" :style="state.largeParentId===item.pointId&&state.largeIndex===index||state.largeParentId===item.pointId&&state.largeIndex===index-4?'border-color:#fff':'border-color:transparent'">
<img :src="item.imgUrl" class="pbBot_img">
<div class="botNamePosition">{{item.name}}</div>
</div>
</div>
</div>
</div>
</div>
</template>
js部分
<script setup>
import { computed, inject, onBeforeUnmount, ref, reactive, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as $cesium from '@/utils/cesium/cesium.js'
const mitter = inject('mitter')
const emit = defineEmits(['closeImgSwitchDialog'])
const props = defineProps({
checkPointImgInfo:Object,
imgSwitchDialog:Boolean,
})
const state = reactive({
//航点信息
lineInfo:[
{
lineId:'10',
pointId:'101',
pointName:'H点1',
pointImg:[{
pointId:'101',
id:'1011',
name:'1点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'101',
id:'1012',
name:'2点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'101',
id:'1013',
name:'特殊点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'101',
id:'1014',
name:'结束点',
imgUrl:'/src/assets/img/login/test.png',
}]
},
{
lineId:'20',
pointId:'201',
pointName:'H点2',
pointImg:[{
pointId:'201',
id:'2011',
name:'1点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'201',
id:'2012',
name:'2点',
imgUrl:'/src/assets/img/login/loginBg.png',
},{
pointId:'201',
id:'2013',
name:'特殊点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'201',
id:'2014',
name:'结束点',
imgUrl:'/src/assets/img/login/test.png',
}]
},
{
lineId:'30',
pointId:'301',
pointName:'H点3',
pointImg:[{
pointId:'301',
id:'3011',
name:'1点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'301',
id:'3012',
name:'2点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'301',
id:'3013',
name:'特殊点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'301',
id:'3014',
name:'结束点',
imgUrl:'/src/assets/img/login/loginBg.png',
}]
},
{
lineId:'40',
pointId:'401',
pointName:'H点4',
pointImg:[{
pointId:'401',
id:'4011',
name:'1点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'401',
id:'4012',
name:'2点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'401',
id:'4013',
name:'特殊点',
imgUrl:'/src/assets/img/login/test.png',
},{
pointId:'401',
id:'4014',
name:'结束点',
imgUrl:'/src/assets/img/login/test.png',
}]
},
],
//图片目录是否展示
imgListShow:true,
//指定H点的图片展示列表
pointImgList:[],
largeImg:'',//放大的图片
pName:'',//H点名称
largeIndex:'',//放大的图片的图片位置
largeParentIndex:'',//放大的图片的图片所在父级的位置
largeParentId:'',//放大的图片的图片所在父级id(H点id)
})
onMounted(()=>{
//默认的H点id
state.largeParentId = '201'
//默认的图片坐标
state.largeIndex = 1
//默认的父级坐标
state.largeParentIndex = 1
//默认的H点名称
state.pName=state.lineInfo[state.largeParentIndex].pointName
//首先默认一进来是这条H线第二个点的第二张图片
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
//默认下方目录的图片列表-图片列表右当前H点和当前H点后一个H点的H点图片组成,判断当前H点所在位置是否为H线最后一个航H点,当为最后一个H点时,拼接第一个H点内容
if(state.largeParentIndex<state.lineInfo.length){
state.pointImgList=state.lineInfo[state.largeParentIndex].pointImg.concat(state.lineInfo[state.largeParentIndex+1].pointImg)
}else if(state.largeParentIndex===state.lineInfo.length){
state.pointImgList=state.lineInfo[state.largeParentIndex].pointImg.concat(state.lineInfo[0].pointImg)
}
})
//点击下方图片列表中图片
const chooseImg = (data,index) =>{
//获取当前图片的所在H点id
state.largeParentId=data.pointId
//获取当前图片的所在H点id的H点位置
state.largeParentIndex=state.lineInfo.findIndex(el=>{
return el.pointId === data.pointId
})
//获取当前图片位置-当当前位置小于H点图片数组长度时,直接赋值,当大于时(一开始拼接4个拼接4个,所以长度是8,每个数组中只有0,1,2,3),使用当前数值减4
if(index<state.lineInfo[state.largeParentIndex].pointImg.length){
state.largeIndex=index
}else{
state.largeIndex=index-4
}
// 点击下方列表图片时,切换上方大图图片内容
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
//获取当前图片的H点名称
state.pName=state.lineInfo[state.largeParentIndex].pointName
}
//点击向左切换按钮
const leftSwitch = () =>{
if(state.largeIndex===0){
//切换后显示的当前图片为前一H点的最后一张图片
//当时H线上第一个H点时,提示已经是第一张图片
if(state.largeParentIndex===0){
ElMessage({
message: '已是该H线的第一个H点中的第一张图片!',
type: 'warning',
})
}else{
//当是H点中第一个图片,再点击切换前一张时,图片列表为当前所在H点与前一H点图片的拼接
state.pointImgList=state.lineInfo[state.largeParentIndex-1].pointImg.concat(state.lineInfo[state.largeParentIndex].pointImg)
//切换后显示的当前图片为前一H点的最后一张图片
state.largeParentIndex=state.largeParentIndex-1
state.largeIndex=3
state.largeParentId=state.lineInfo[state.largeParentIndex].pointId
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
}
}else if(state.largeIndex>0&&state.largeIndex<4){
//当是中间图片或最后一张图片时,只切换当前图片的位置向前一个
state.largeIndex=state.largeIndex-1
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
}
//获取当前图片的H点名称
state.pName=state.lineInfo[state.largeParentIndex].pointName
}
//点击向右切换按钮
const rightSwitch = () =>{
if(state.largeIndex===3){
//当是H点中最后一个图片,再点击切换后一张时,图片列表为当前所在H点与后一H点图片的拼接
//当时H线上最后一个H点时,提示已经是最后一张图片
if(state.largeParentIndex<3){
state.pointImgList=state.lineInfo[state.largeParentIndex].pointImg.concat(state.lineInfo[state.largeParentIndex+1].pointImg)
//切换后显示的当前图片为后一H点的第一张图片
state.largeParentIndex=state.largeParentIndex+1
state.largeIndex=0
state.largeParentId=state.lineInfo[state.largeParentIndex].pointId
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
}else{
ElMessage({
message: '已是该H线的最后一个H点中的最后一张图片!',
type: 'warning',
})
}
}else if(state.largeIndex<3){
//当是中间图片或第一张图片时,只切换当前图片的位置向后一个
state.largeIndex=state.largeIndex+1
state.largeImg=state.lineInfo[state.largeParentIndex].pointImg[state.largeIndex].imgUrl
}
//获取当前图片的H点名称
state.pName=state.lineInfo[state.largeParentIndex].pointName
}
</script>
css部分
<style lang="scss" scoped>
.pointImgDialog{
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
width: 60%;
height: 70%;
background: rgba(0, 0, 0, 1);
color: #fff;
}
.pointAll {
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
padding: 0.05rem 0.08rem;
&_top{
flex: 1;
height: 65%;
display: flex;
flex-direction: column;
width: 100%;
.ptTop{
display: flex;
justify-content: flex-end;
background: rgba(0, 0, 0, 0.17);
}
.ptBot{
flex: 1;
display: flex;
align-items: center;
margin: 10px 0;
&_left{
width: 15%;
display: flex;
justify-content: center;
}
&_cen{
flex: 70%;
height: 100%;
border: 1px solid rgba(255, 255, 255, 0.2);
display: flex;
justify-content: center;
align-items: center;
position: relative;
.cenImg{
max-height: 100%;
max-width: 100%;
}
.cenNamePosition{
position: absolute;
top: 0;
left: 0;
right: 0;
height: 20px;
background: rgba(0, 0, 0, 0.17);
text-align: center;
line-height: 20px;
color: #fff;
}
}
&_right{
width: 15%;
display: flex;
justify-content: center;
}
.icon{
width: 0.2rem;
height: 0.2rem;
border-radius: 50%;
display: flex;
justify-content: center;
align-items: center;
background: rgba(255,255,255,0.24);
}
.iconStyle{
font-size: 20px;
}
}
}
&_bot{
height: 18%;
width: 100%;
display: flex;
flex-direction: column;
.pbTop{
display: flex;
justify-content: center;
&_icon{
height: 0.08rem;
width: 0.24rem;
background: rgba(255,255,255,0.24);
border-radius: 4px 4px 0 0;
text-align: center;
}
}
.pbBot{
background: rgba(255,255,255,0.24);
border-radius: 8px 8px 0 0;
height: 95%;
width: 100%;
overflow: hidden;
display: flex;
justify-content: space-around;
align-items: center;
.pbBotItem{
width: 11%;
height: 88%;
border: 1px solid transparent;
position: relative;
}
&_img{
width: 100%;
height: 100%;
}
.botNamePosition{
position: absolute;
bottom: 0;
left: 0;
right: 0;
height: 14px;
line-height: 14px;
text-align: center;
background: rgba(0, 0, 0, 0.32);
color: #fff;
font-size: 12px;
}
}
}
}
:deep(.el-dialog__header){
display: none;
}
:deep(.el-dialog__body){
padding: 0.1rem;
color:#fff;
}
:deep(.el-dialog){
height: 70%;
background: #000;
}