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