162 lines
3.8 KiB
Vue
Raw Normal View History

<template>
<Transition name="location-panel">
<section
v-if="expanded"
:id="panelId"
class="location-panel"
role="region"
:aria-labelledby="labelId || undefined"
:aria-label="!labelId ? '地理位置信息' : undefined"
>
<div class="location-grid">
<article
v-for="item in locationInfo"
:key="item.label"
class="info-card"
>
<img
class="info-icon"
:src="item.icon"
alt=""
aria-hidden="true"
/>
<div class="info-content">
<p class="info-label">{{ item.label }}</p>
<p class="info-value" :title="item.value">{{ item.value }}</p>
</div>
</article>
</div>
</section>
</Transition>
</template>
<script setup>
import lineCodeIcon from '../../assets/images/LocationPanel/线路编号icon.png'
import classNumberIcon from '../../assets/images/LocationPanel/路线桩号icon.png'
import inspectorIcon from '../../assets/images/LocationPanel/路段巡查员icon.png'
import phoneIcon from '../../assets/images/LocationPanel/联系电话icon.png'
defineProps({
expanded: {
type: Boolean,
default: true,
},
panelId: {
type: String,
default: 'location-panel',
},
labelId: {
type: String,
default: '',
},
})
// 地理位置信息数据
const locationInfo = [
{ label: '线路编号', value: 'S710', icon: lineCodeIcon },
{ label: '路线班号', value: 'S199', icon: classNumberIcon },
{ label: '路段巡查员', value: '张强', icon: inspectorIcon },
{ label: '联系电话', value: '13987657892', icon: phoneIcon },
]
</script>
<style scoped lang="scss">
@use '@/styles/mixins.scss' as *;
@use '../../assets/styles/common.scss' as *;
.location-panel {
width: 100%;
padding: clamp(12px, vh(16), 20px) clamp(16px, vw(20), 28px);
background: url('../../assets/images/LocationPanel/地理位置内容背景.png') no-repeat center center;
background-size: 100% 100%;
border-radius: vw(8);
box-shadow: 0 0 vw(12) rgba(0, 0, 0, 0.35);
overflow: hidden;
min-width: 240px;
max-width: 100%;
// min-height: 160px;
}
// 2x2 网格布局
.location-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
grid-template-rows: repeat(2, minmax(0, 1fr));
gap: clamp(10px, vh(14), 18px) clamp(12px, vw(16), 20px);
width: 100%;
height: 100%;
}
// 信息卡片
.info-card {
display: flex;
align-items: center;
gap: clamp(8px, vw(12), 14px);
// padding: clamp(10px, vh(12), 16px) clamp(12px, vw(14), 18px);
// background: rgba(10, 95, 165, 0.15);
border-radius: clamp(6px, vw(8), 10px);
// border: 1px solid rgba(135, 206, 250, 0.12);
min-width: 0;
transition: background-color 0.3s ease, border-color 0.3s ease;
&:hover {
background: rgba(10, 95, 165, 0.22);
border-color: rgba(135, 206, 250, 0.2);
}
}
// 图标样式
.info-icon {
width: clamp(24px, vw(32), 40px);
height: clamp(24px, vw(32), 40px);
flex-shrink: 0;
object-fit: contain;
}
// 文本内容区域
.info-content {
display: flex;
flex-direction: column;
gap: clamp(3px, vh(4), 6px);
flex: 1;
min-width: 0;
}
// 标签样式
.info-label {
margin: 0;
font-size: clamp(12px, vw(14), 16px);
color: #87ceeb;
line-height: 1.3;
font-weight: 400;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
// 值样式
.info-value {
margin: 0;
font-size: clamp(15px, vw(18), 22px);
color: #e8f4ff;
font-weight: 600;
line-height: 1.2;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
letter-spacing: 0.5px;
}
// 过渡动画
.location-panel-enter-active,
.location-panel-leave-active {
transition: all 0.3s ease;
}
.location-panel-enter-from,
.location-panel-leave-to {
opacity: 0;
transform: translateY(vh(-10));
}
</style>