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>

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

相关推荐
小葛要努力19 小时前
创建vue2项目
程序人生·vue
七仔啊20 小时前
基于海康门禁的人员计数系统
vue
步十人2 天前
【Vue3】前置知识简单概述(包括ES6核心语法,模块化ESM以及npm基础)
arcgis·npm·vue·es6
有梦想的程序星空2 天前
【环境配置】Vue3项目离线化本地部署echarts全攻略
前端·javascript·vue·echarts
向日的葵0063 天前
vue路由(二)
前端·javascript·vue.js·vue
小妖6664 天前
Hydration completed but contains mismatches
javascript·vue·vuepress
lianyinghhh4 天前
FlowGame 从零上手:开源 AI 工作流编排框架与 Vue 3 接入实战
python·低代码·开源·vue·rag·flowgame·ai工作流编排
爱编程的小金4 天前
告别手写分页逻辑:usePagination 从 50 行到 3 行
javascript·vue·前端分页·alova·usepagination
ok406lhq4 天前
用 MonkeyCode 8 小时搭建自动化内容站:AI Coding 平台实战复盘
ci/cd·vue·ai编程·自动化部署·monkeycode
brycegao3215 天前
Tauri2+Vue3+Ollama 实战|依托 AI 协同开发全离线隐私记账桌面软件(开源)
人工智能·开源·vue·ai编程·tauri·ollama·桌面开发