vue2 精细级别判断图片页面

逻辑:listdata 获取 他的宽度 来减去当前一行可以容纳多少 image-item 然后在通过剩余的值去平均分给 image-item 剩余的值

javascript 复制代码
<template>
  <div class="Celebimagecharacter">
    <Row>
      <Col :span="12">
        <div class="basic-info-card-title" style="margin-top: 6px">
          已匹配源人物
          <span style="margin-left: 6px; color: rgb(153, 153, 153); font-size: 12px">{{ 0 }}</span>
        </div>
      </Col>
      <Col :span="12" style="text-align: right; padding-right: 32px">
        <Button type="primary" @click="openCelebimagecharacterDlog">全部</Button>
      </Col>
    </Row>
    <Row>
      <Col :span="24">
        <div ref="listdata" class="listdata">
          <div
            class="image-item"
            v-for="(item, index) in [1,2,3,4,5,5,5,4,5,5,5,5,5,5,5,5,5,5]"
            :key="index"
            :style="itemStyle"
          >
            <img
              :src="defaultImage"
              class="image-content"
              alt="人物图片"
              @error="handleImgError"
            />
          </div>
        </div>
      </Col>
    </Row>
    <!-- <CelebimagecharacterDlog
          ref="CelebimagecharacterDlog"
          :is-edited="editModal.relation"
          :base-ps-id="openTagBasePsId"
          :baseOpType="baseOpType"
          :create-source-ps-id="basePs.createSourcePsId"
          @showSourcePsDetail="showSourcePsDetail"
          @update-source-ps-list-total="handleSourcePsListUpdateTotal"
        ></CelebimagecharacterDlog> -->
    <!-- <CelebimagecharacterDlog ref="CelebimagecharacterDlog"></CelebimagecharacterDlog> -->
  </div>
</template>
<script>
import CelebimagecharacterDlog from './pop-up/CelebimagecharacterDlog.vue';
export default {
  components: {
    CelebimagecharacterDlog,
  },
  props: {
    basePsId: {
      type: String,
      default: '',
    },
    isEdited: {
      type: Boolean,
      default: false,
    },
    baseOpType: {
      type: String,
      default: 'NONE',
    },
    createSourcePsId: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      drawerVisible: false,
      sourcePsList: [],
      defaultImage: require('../../../../images/add.png'),
      // 调整:默认尺寸与最小尺寸保持一致
      itemWidth: 160,
      resizeTimer: null,
    };
  },
  computed: {
    itemStyle() {
      return {
        width: `${this.itemWidth}px`,
        // 保持1:1.5的宽高比(160x240)
        height: `${Math.floor(this.itemWidth * 1.5)}px`,
        // 调整CSS层防护与JS计算逻辑一致
        maxWidth: '200px',
        maxHeight: '300px',
        minWidth: '160px',  // 修改为160,确保最小尺寸
        minHeight: '240px', // 修改为240,确保最小尺寸
      };
    },
  },
  methods: {
    getSourceCodes() {},
    openCelebimagecharacterDlog() {
      this.$refs.CelebimagecharacterDlog.openDrawer();
    },
    handleImgError(e) {
      // 图片加载失败时降级显示,避免裂图
      e.target.style.objectFit = 'contain';
      e.target.style.padding = '20px';
      e.target.style.opacity = '0.5';
    },
    
    // 调整:动态计算item宽度,以160为基准
    calculateItemWidth() {
      const container = this.$refs.listdata;
      if (!container) return;
      
      const containerWidth = container.clientWidth;
      const gap = 12;
      const targetWidth = 160; // 目标宽度
      const safetyMargin = 4;  // 减少安全余量,避免过度压缩
      
      // 计算一行可容纳多少个160px的项
      const estimatedCount = Math.floor((containerWidth + gap) / (targetWidth + gap));
      const itemsPerRow = Math.max(1, estimatedCount);
      
      // 平均分配宽度,但确保不小于160
      const totalGapWidth = (itemsPerRow - 1) * gap;
      const availableWidth = containerWidth - totalGapWidth - safetyMargin;
      const calculatedWidth = Math.floor(availableWidth / itemsPerRow);
      
      // 应用边界限制:最小160,最大200
      this.itemWidth = Math.max(160, Math.min(200, calculatedWidth));
    },
    
    // 新增:防抖处理的resize监听
    handleResize() {
      clearTimeout(this.resizeTimer);
      // 调整:延长防抖时间,减少计算频率
      this.resizeTimer = setTimeout(() => {
        this.calculateItemWidth();
      }, 300);
    },
  },
  mounted() {
    this.getSourceCodes();
    // 新增:初始化时计算宽度
    this.$nextTick(() => {
      this.calculateItemWidth();
    });
    // 新增:监听窗口变化
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    // 新增:清理事件监听
    window.removeEventListener('resize', this.handleResize);
    clearTimeout(this.resizeTimer);
  },
};
</script>
<style lang="less" scoped>
.listdata {
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  padding: 8px 0;
}

.image-item {
  border-radius: 4px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
  cursor: pointer;
  background-color: #f5f5f5;
  flex-shrink: 0;
  
  &:hover {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    transform: translateY(-2px);
  }
}

.image-content {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
</style>

要稍微减少一点点 留一点点备用空间

相关推荐
还得是你大哥5 小时前
Java互联网医院管理系统源码SpringBoot
java·spring boot·vue
会周易的程序员11 小时前
aiDgeScanner:工业设备扫描与管理的一体化利器——深度解析上位机与扫描端的无缝协作
c++·物联网·typescript·electron·vue·iot·aiot
阿部多瑞 ABU18 小时前
运动会智能编排系统 - 完整详细需求规格说明书
python·贪心算法·vue·html
AIGC包拥它1 天前
RAG 项目实战进阶:基于 FastAPI + Vue3 前后端架构全面重构 LangChain 0.3 集成 Milvus 2.5 构建大模型智能应用
人工智能·python·重构·vue·fastapi·milvus·ai-native
次次皮3 天前
代理启动前端dist包
java·前端·vue
展示猪肝3 天前
Vue2 + FastAPI + Dify 实现 AI 医疗预检分诊助手:从问诊追问到医生审核闭环
人工智能·vue·fastapi·dify
何忆清风4 天前
Easy Agent Pilot - Rust实现的开源桌面Agent软件
ai·rust·vue·agent·tauri·开发工具
码界筑梦坊4 天前
361-基于Python的空气质量气候数据分析预测系统
python·信息可视化·数据分析·flask·vue·毕业设计
我叫张小白。4 天前
劳动力招聘管理系统:全栈实战(Vue3+FastAPI+WebSocket+Dify)
websocket·vue·毕业设计·状态模式·fastapi·dify·智能体