逻辑: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>
要稍微减少一点点 留一点点备用空间