mirror of
https://github.com/palxiao/poster-design.git
synced 2025-07-15 16:02:19 +08:00
fix: water-fall image list
This commit is contained in:
parent
91213c4f97
commit
4467227b47
@ -2,15 +2,15 @@
|
||||
* @Author: ShawnPhang
|
||||
* @Date: 2021-12-16 16:20:16
|
||||
* @Description: 瀑布流组件
|
||||
* @LastEditors: ShawnPhang <site: book.palxp.com>
|
||||
* @LastEditTime: 2023-07-06 17:58:49
|
||||
* @LastEditors: ShawnPhang <https://m.palxp.cn>
|
||||
* @LastEditTime: 2023-10-03 22:58:32
|
||||
-->
|
||||
<template>
|
||||
<div ref="imgWaterFall" :style="{ height: countHeight + 'px' }" class="img-water-fall">
|
||||
<!-- backgroundImage: `url(${item.cover})` -->
|
||||
<div v-for="(item, index) in list" :key="index + 'iwf'" :style="{ top: item.top + 'px', left: item.left + 'px', width: width + 'px', height: item.height + 'px' }" class="img-box" @click.stop="selectItem(item, index)">
|
||||
<v-lazy-image v-if="!item.fail" class="img" @error="loadError(item)" :src="item.cover" />
|
||||
<div class="fail_img" v-else>{{ item.title }}</div>
|
||||
<v-lazy-image v-if="!item.fail" class="img" :src="item.cover" @error="loadError(item)" />
|
||||
<div v-else class="fail_img">{{ item.title }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -18,12 +18,9 @@
|
||||
<script>
|
||||
import vLazyImage from 'v-lazy-image'
|
||||
const NAME = 'img-water-fall'
|
||||
// import api from '@/api/album'
|
||||
const columnHeights = [] // 列的高度
|
||||
const columnNums = 2 // 总共有多少列
|
||||
const gap = 7 // 图片之间的间隔
|
||||
import { defineComponent, toRefs, reactive, watch } from 'vue'
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: NAME,
|
||||
components: { vLazyImage },
|
||||
props: {
|
||||
@ -31,63 +28,65 @@ export default {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
// scroll: {
|
||||
// default: true,
|
||||
// },
|
||||
},
|
||||
emits: ['select', 'load'],
|
||||
data() {
|
||||
return {
|
||||
setup(props, { emit }) {
|
||||
const state = reactive({
|
||||
width: 146, // 图片的宽度
|
||||
list: [],
|
||||
countHeight: 0,
|
||||
})
|
||||
|
||||
const columnHeights = [] // 列的高度
|
||||
const columnNums = 2 // 总共有多少列
|
||||
const gap = 7 // 图片之间的间隔
|
||||
|
||||
watch(
|
||||
() => props.listData,
|
||||
() => {
|
||||
columnHeights.length = 0
|
||||
const widthLimit = state.width * columnNums // + gap * (columnNums - 1) // 每行宽度
|
||||
const cloneList = JSON.parse(JSON.stringify(props.listData))
|
||||
for (let i = 0; i < cloneList.length; i++) {
|
||||
let index = i % columnNums
|
||||
const item = cloneList[i]
|
||||
item.height = (item.height / item.width) * state.width // 图片高度
|
||||
item.left = index * (widthLimit / columnNums + gap) // 定位
|
||||
item.top = columnHeights[index] + gap || 0 // 定位
|
||||
// columnHeights[index] = isNaN(columnHeights[index]) ? item.height : item.height + columnHeights[index] + gap // 记录列高度
|
||||
// 找出最短边
|
||||
if (isNaN(columnHeights[index])) {
|
||||
columnHeights[index] = item.height
|
||||
} else {
|
||||
index = columnHeights.indexOf(Math.min(...columnHeights))
|
||||
item.left = index * (widthLimit / columnNums + gap)
|
||||
item.top = columnHeights[index] + gap || 0
|
||||
columnHeights[index] = item.height + columnHeights[index] + gap
|
||||
}
|
||||
}
|
||||
state.countHeight = Math.max(...columnHeights)
|
||||
state.list = cloneList
|
||||
},
|
||||
)
|
||||
|
||||
const load = () => {
|
||||
emit('load')
|
||||
}
|
||||
const selectItem = (value, index) => {
|
||||
emit('select', value)
|
||||
}
|
||||
const loadError = (item) => {
|
||||
item.fail = true
|
||||
}
|
||||
|
||||
return {
|
||||
...toRefs(state),
|
||||
load,
|
||||
selectItem,
|
||||
loadError,
|
||||
}
|
||||
},
|
||||
// async mounted() {
|
||||
|
||||
// },
|
||||
watch: {
|
||||
listData() {
|
||||
columnHeights.length = 0
|
||||
const widthLimit = this.width * columnNums // + gap * (columnNums - 1) // 每行宽度
|
||||
const cloneList = JSON.parse(JSON.stringify(this.listData))
|
||||
let lineWidth = 0
|
||||
let index = 0
|
||||
for (let i = 0; i < cloneList.length; i++) {
|
||||
const item = cloneList[i]
|
||||
const r = item.width / this.width
|
||||
item.height = item.height / r
|
||||
lineWidth += this.width
|
||||
if (lineWidth >= widthLimit) {
|
||||
index++
|
||||
item.left = this.width + gap
|
||||
item.top = columnHeights[index] + gap || 0
|
||||
columnHeights[index] = typeof columnHeights[index] === 'number' ? item.height + columnHeights[index] + gap : item.height
|
||||
// init
|
||||
lineWidth = 0
|
||||
index = 0
|
||||
} else {
|
||||
item.top = columnHeights[index] + gap || 0
|
||||
item.left = 0
|
||||
columnHeights[index] = typeof columnHeights[index] === 'number' ? item.height + columnHeights[index] + gap : item.height
|
||||
}
|
||||
}
|
||||
this.countHeight = Math.max(...columnHeights)
|
||||
this.list = cloneList
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
this.$emit('load')
|
||||
},
|
||||
selectItem(value, index) {
|
||||
this.$emit('select', value)
|
||||
},
|
||||
loadError(item) {
|
||||
item.fail = true
|
||||
},
|
||||
},
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
Loading…
x
Reference in New Issue
Block a user