dma_handbook/docs/.vuepress/components/longPic.vue

152 lines
3.3 KiB
Vue
Raw Normal View History

2025-09-29 16:51:36 +08:00
<script setup>
2026-02-06 11:17:10 +08:00
import { ref, onMounted, watch } from 'vue'
2025-09-29 16:51:36 +08:00
const props = defineProps({
src: {
type: String,
required: true
},
alt: {
type: String,
default: '图片'
},
maxHeight: {
type: Number,
default: 500
}
})
const isExpanded = ref(false)
const showExpand = ref(false)
2026-02-06 11:17:10 +08:00
// 标记图片是否已加载,防止@load重复触发
const isImageLoaded = ref(false)
// 核心VuePress SSR适配仅在浏览器端执行图片高度判断
const checkImageHeight = (img) => {
if (typeof window === 'undefined') return // 服务端直接返回
const naturalHeight = img.naturalHeight || img.offsetHeight
console.log(props.alt, naturalHeight, '图片实际高度')
showExpand.value = naturalHeight > props.maxHeight
isImageLoaded.value = true
}
2025-09-29 16:51:36 +08:00
2026-02-06 11:17:10 +08:00
// 图片加载完成触发
2025-09-29 16:51:36 +08:00
const handleImageLoad = (event) => {
2026-02-06 11:17:10 +08:00
if (isImageLoaded.value) return
checkImageHeight(event.target)
2025-09-29 16:51:36 +08:00
}
2026-02-06 11:17:10 +08:00
// 浏览器端挂载后,主动检查图片(解决@load未触发的边界情况
onMounted(() => {
if (typeof window === 'undefined') return
const img = document.querySelector(`.responsive-image[src="${props.src}"]`)
if (img && img.complete) { // 图片已缓存完成,主动触发高度判断
checkImageHeight(img)
}
})
// 展开/收起切换
2025-09-29 16:51:36 +08:00
const toggleExpand = () => {
isExpanded.value = !isExpanded.value
}
2026-02-06 11:17:10 +08:00
// 监听展开状态,同步更新提示显示(兜底)
watch(isExpanded, (val) => {
if (!showExpand.value) return
showExpand.value = !val
})
2025-09-29 16:51:36 +08:00
</script>
<template>
<div class="image-container">
<div
2026-02-06 11:17:10 +08:00
class="image-wrapper"
:class="{ 'expanded': isExpanded }"
:style="{ maxHeight: !isExpanded ? `${maxHeight}px` : 'none' }"
2025-09-29 16:51:36 +08:00
>
<img
2026-02-06 11:17:10 +08:00
:src="src"
:alt="alt"
@load="handleImageLoad"
class="responsive-image"
loading="lazy"
2025-09-29 16:51:36 +08:00
>
</div>
2026-02-06 11:17:10 +08:00
<!-- 展开提示仅图片高度超限时显示 -->
<div v-if="showExpand" class="expand-hint" @click="toggleExpand" v-show="!isExpanded">
2025-09-29 16:51:36 +08:00
<span>点击查看完整图片</span>
</div>
2026-02-06 11:17:10 +08:00
<!-- 收起提示仅展开后显示 -->
<div class="collapse-hint" @click="toggleExpand" v-show="isExpanded">
2025-09-29 16:51:36 +08:00
<span>收起图片</span>
</div>
</div>
</template>
<style scoped>
.image-container {
position: relative;
width: 100%;
2026-02-06 11:17:10 +08:00
margin: 0 auto;
2025-09-29 16:51:36 +08:00
}
.image-wrapper {
width: 100%;
overflow: hidden;
2026-02-06 11:17:10 +08:00
transition: max-height 0.3s ease-in-out;
2025-09-29 16:51:36 +08:00
position: relative;
}
2026-02-06 11:17:10 +08:00
/* 渐变遮罩:仅未展开时显示,提示有更多内容 */
.image-wrapper:not(.expanded)::after {
2025-09-29 16:51:36 +08:00
content: '';
position: absolute;
bottom: 0;
left: 0;
right: 0;
2026-02-06 11:17:10 +08:00
height: 80px;
background: linear-gradient(transparent, rgba(255,255,255,0.95));
2025-09-29 16:51:36 +08:00
pointer-events: none;
}
.image-wrapper.expanded::after {
display: none;
}
.responsive-image {
width: 100%;
height: auto;
display: block;
}
2026-02-06 11:17:10 +08:00
.expand-hint, .collapse-hint {
2025-09-29 16:51:36 +08:00
text-align: center;
padding: 8px;
border-radius: 4px;
font-size: 14px;
2026-02-06 11:17:10 +08:00
cursor: pointer;
margin-top: 8px;
2025-09-29 16:51:36 +08:00
transition: background-color 0.3s;
}
2026-02-06 11:17:10 +08:00
.expand-hint {
background: rgba(64, 158, 255, 0.1);
color: #409eff;
}
2025-09-29 16:51:36 +08:00
.expand-hint:hover {
background: rgba(64, 158, 255, 0.2);
}
.collapse-hint {
background: rgba(103, 194, 58, 0.1);
color: #67c23a;
}
.collapse-hint:hover {
background: rgba(103, 194, 58, 0.2);
}
</style>