< template>
< div class = " container" >
< div v-if = " !isLayoutReady" class = " temp-container" >
< div
v-for = " (item, index) in list"
:key = " ' temp-' + index"
:ref = " (el) => (tempElements[index] = el)"
class = " item"
>
< img :src = " item.url" alt = " " @load = " handleImageLoad" />
</ div>
</ div>
< template v-else >
< div class = " column" >
< div
v-for = " (item, index) in leftList"
:key = " ' left-' + index"
class = " item"
>
< img :src = " item.url" alt = " " />
< div class = " demo-title" > {{ item.title }}</ div>
< div class = " demo-times" > {{ item.descript }}</ div>
< div class = " demo-tag" >
< div class = " demo-tag-owner" > {{ item.tag[0] }}</ div>
< div class = " demo-tag-text" > {{ item.tag[1] }}</ div>
</ div>
< div v-if = " item.isDot" class = " isDot" > {{ item.isDot }}</ div>
</ div>
</ div>
< div class = " column" >
< div
v-for = " (item, index) in rightList"
:key = " ' right-' + index"
class = " item"
>
< img :src = " item.url" alt = " " />
< div class = " demo-title" > {{ item.title }}</ div>
< div class = " demo-times" > {{ item.descript }}</ div>
< div class = " demo-tag" >
< div class = " demo-tag-owner" > {{ item.tag[0] }}</ div>
< div class = " demo-tag-text" > {{ item.tag[1] }}</ div>
</ div>
< div v-if = " item.isDot" class = " isDot" > {{ item.isDot }}</ div>
</ div>
</ div>
</ template>
</ div>
</ template>
< script>
export default {
data ( ) {
return {
list: [
{
url: "https://img0.baidu.com/it/u=4227008132,2843866888&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1084" ,
title: "清新世界" ,
descript: "一年之计在于春" ,
tag: [ "阳光" , "活力四射" ] ,
isDot: "推荐" ,
} ,
{
url: "http://img2.baidu.com/it/u=3364932024,431806429&fm=253&app=138&f=JPEG?w=800&h=1422" ,
title: "雪国列车" ,
descript: "雪花纷纷极具寒冷" ,
tag: [ "冰冻" , "别具一格" ] ,
isDot: "推荐" ,
} ,
{
url: "https://img0.baidu.com/it/u=600722015,3838115472&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=750" ,
title: "漂亮的小鸟" ,
descript: "麻雀安知鸿鹄之志" ,
tag: [ "等待" , "翘首以盼" ] ,
isDot: "" ,
} ,
{
url: "https://img0.baidu.com/it/u=4227008132,2843866888&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=1084" ,
title: "清新世界" ,
descript: "一年之计在于春" ,
tag: [ "阳光" , "活力四射" ] ,
isDot: "推荐" ,
} ,
{
url: "http://img2.baidu.com/it/u=3364932024,431806429&fm=253&app=138&f=JPEG?w=800&h=1422" ,
title: "雪国列车" ,
descript: "雪花纷纷极具寒冷" ,
tag: [ "冰冻" , "别具一格" ] ,
isDot: "推荐" ,
} ,
] ,
leftList: [ ] ,
rightList: [ ] ,
tempElements: [ ] ,
loadedImages: 0 ,
isLayoutReady: false ,
}
} ,
mounted ( ) {
this . preloadImages ( )
} ,
methods: {
preloadImages ( ) {
this . list. forEach ( ( item ) => {
const img = new Image ( )
img. src = item. url
} )
} ,
handleImageLoad ( ) {
this . loadedImages++
if ( this . loadedImages === this . list. length) {
this . calculateLayout ( )
}
} ,
calculateLayout ( ) {
this . $nextTick ( ( ) => {
const itemHeights = this . tempElements. map ( ( el ) => el. clientHeight)
let leftHeight = 0
let rightHeight = 0
this . list. forEach ( ( item, index ) => {
if ( leftHeight <= rightHeight) {
this . leftList. push ( item)
leftHeight += itemHeights[ index]
} else {
this . rightList. push ( item)
rightHeight += itemHeights[ index]
}
} )
this . isLayoutReady = true
} )
} ,
} ,
}
< / script>
<style scoped>
.container {
display : flex;
gap : 20px;
max-width : 400px;
margin : 0 auto;
padding : 20px;
}
.column {
flex : 1;
display : flex;
flex-direction : column;
gap : 20px;
}
.item {
position : relative;
background : white;
border-radius : 8px;
padding : 15px;
box-shadow : 0 2px 8px rgba ( 0, 0, 0, 0.1) ;
}
.item img {
width : 100%;
height : 68%;
border-radius : 4px;
margin-bottom : 12px;
}
.demo-title {
font-size : 18px;
font-weight : 600;
margin-bottom : 8px;
color : #333;
}
.demo-times {
font-size : 14px;
color : #666;
margin-bottom : 12px;
}
.demo-tag {
display : flex;
gap : 10px;
}
.demo-tag-owner,
.demo-tag-text {
padding : 4px 12px;
border-radius : 20px;
font-size : 12px;
}
.demo-tag-owner {
background : #fff0e6;
color : #ff6600;
border : 1px solid #ffd8c2;
}
.demo-tag-text {
background : #e6f7ff;
color : #1890ff;
border : 1px solid #b3e0ff;
}
.isDot {
position : absolute;
top : 15px;
right : 15px;
background : #ff4d4f;
color : white;
padding : 4px 10px;
border-radius : 4px;
font-size : 12px;
}
.temp-container {
position : absolute;
visibility : hidden;
z-index : -1;
}
</style>