插件 npm install vue-waterfall-plugin-next
或者 yarn add vue-waterfall-plugin-next
点击vue-waterfall-plugin-next进入文档
组件
<template>
<Waterfall :lazyload="false" :breakpoints="breakpoints" :gutter="8" :list="list" :column-count="3">
<template #item="{ item }">
<div class="card_content">
<div class="card_img" :class="{ active: !item.goodsPicture && !item.storePicture }">
<LazyImg class="cover" :url="item.src" />
</div>
<div>
title
</div>
</div>
</template>
</Waterfall>
</template>
<script setup>
import { computed, ref } from 'vue'
import { LazyImg, Waterfall } from 'vue-waterfall-plugin-next'
import 'vue-waterfall-plugin-next/dist/style.css'
const props = defineProps({
productList: {
type: Array
}
})
const list = computed(() => {
return props.productList
})
const breakpoints = ref({
3000: {
//当屏幕宽度小于等于3000
rowPerView: 8, // 一行8图
},
1800: {
//当屏幕宽度小于等于1800
rowPerView: 6,// 一行6图
},
1200: {
//当屏幕宽度小于等于1200
rowPerView: 4,
},
500: {
//当屏幕宽度小于等于500
rowPerView: 2,
},
})
</script>
<style lang="scss" scoped>
.card_content {
border-radius: 4px;
background: #fff;
box-sizing: border-box;
.card_img {
margin-bottom: 7px;
&.active {
border: 1px solid #e7e7e7;
}
:deep(.lazy__img) {
width: 100%;
border-radius: 4px;
font-size: 0;
height: 100%;
}
}
.content {
padding: 0 8px;
.store {
color: rgba(0, 0, 0, 0.4);
font-size: 12px;
font-weight: 400;
margin-bottom: 4px;
}
.title {
font-size: 16px;
font-weight: 500;
margin-bottom: 14px;
}
.tags {
display: flex;
flex-wrap: wrap;
.tags-item {
background: rgba(153, 151, 255, 0.05);
border-radius: 2px;
padding: 3px 4px;
margin: 0 5px 5px 0;
color: rgba(0, 0, 0, 0.4);
font-size: 12px;
border: 1px solid rgb(244, 244, 249);
&:last-child {
margin-right: 0;
}
}
}
}
}
</style>
使用组件
// 父组件index.vue
<template>
<div class="container" id="main">
<productCard :productList="productList"></productCard>
<div class="loading-text" v-if="loading">加载中...</div>
<div class="loading-text" v-if="finish">没有更多了</div>
</div>
</template>
<script setup>
import productCard from './components/index.vue'
const loading = ref(false)
const finish = ref(false)
let arr = [
{
id: 1,
src: 'https://www.qianduange.cn/upload/article/img1.jpg'
},
{
id: 2,
src: 'https://www.qianduange.cn/upload/article/img2.jpg'
},
{
id: 3,
src: 'https://www.qianduange.cn/upload/article/img3.jpg'
},
{
id: 4,
src: 'https://www.qianduange.cn/upload/article/img4.jpg'
},
{
id: 5,
src: 'https://www.qianduange.cn/upload/article/img5.jpg'
},
{
id: 6,
src: 'https://www.qianduange.cn/upload/article/img6.jpg'
},
{
id: 7,
src: 'https://www.qianduange.cn/upload/article/img7.jpg'
},
{
id: 8,
src: 'https://www.qianduange.cn/upload/article/img8.jpg'
},
{
id: 9,
src: 'https://www.qianduange.cn/upload/article/img9.jpg'
},
{
id: 10,
src: 'https://www.qianduange.cn/upload/article/img10.jpg'
},
{
id: 11,
src: 'https://www.qianduange.cn/upload/article/img11.jpg'
},
{
id: 12,
src: 'https://www.qianduange.cn/upload/article/img12.jpg'
},
{
id: 13,
src: 'https://www.qianduange.cn/upload/article/img13.jpg'
},
{
id: 14,
src: 'https://www.qianduange.cn/upload/article/img14.jpg'
},
{
id: 15,
src: 'https://www.qianduange.cn/upload/article/img15.jpg'
},
{
id: 16,
src: 'https://www.qianduange.cn/upload/article/img16.jpg'
},
{
id: 17,
src: 'https://www.qianduange.cn/upload/article/img17.jpg'
},
{
id: 18,
src: 'https://www.qianduange.cn/upload/article/img18.jpg'
},
{
id: 19,
src: 'https://www.qianduange.cn/upload/article/img19.jpg'
},
{
id: 20,
src: 'https://www.qianduange.cn/upload/article/img20.jpg'
},
{
id: 21,
src: 'https://www.qianduange.cn/upload/article/img21.jpg'
},
{
id: 22,
src: 'https://www.qianduange.cn/upload/article/img22.jpg'
},
{
id: 23,
src: 'https://www.qianduange.cn/upload/article/img23.jpg'
},
{
id: 24,
src: 'https://www.qianduange.cn/upload/article/img24.jpg'
},
{
id: 25,
src: 'https://www.qianduange.cn/upload/article/img25.jpg'
}
]
let productList = ref([
{
id: 1,
src: 'https://www.qianduange.cn/upload/article/img1.jpg'
},
{
id: 2,
src: 'https://www.qianduange.cn/upload/article/img2.jpg'
},
{
id: 3,
src: 'https://www.qianduange.cn/upload/article/img3.jpg'
},
{
id: 4,
src: 'https://www.qianduange.cn/upload/article/img4.jpg'
},
{
id: 5,
src: 'https://www.qianduange.cn/upload/article/img5.jpg'
},
{
id: 6,
src: 'https://www.qianduange.cn/upload/article/img6.jpg'
},
{
id: 7,
src: 'https://www.qianduange.cn/upload/article/img7.jpg'
},
{
id: 8,
src: 'https://www.qianduange.cn/upload/article/img8.jpg'
},
{
id: 9,
src: 'https://www.qianduange.cn/upload/article/img9.jpg'
},
{
id: 10,
src: 'https://www.qianduange.cn/upload/article/img10.jpg'
},
{
id: 11,
src: 'https://www.qianduange.cn/upload/article/img11.jpg'
},
{
id: 12,
src: 'https://www.qianduange.cn/upload/article/img12.jpg'
},
{
id: 13,
src: 'https://www.qianduange.cn/upload/article/img13.jpg'
},
{
id: 14,
src: 'https://www.qianduange.cn/upload/article/img14.jpg'
},
{
id: 15,
src: 'https://www.qianduange.cn/upload/article/img15.jpg'
},
{
id: 16,
src: 'https://www.qianduange.cn/upload/article/img16.jpg'
},
{
id: 17,
src: 'https://www.qianduange.cn/upload/article/img17.jpg'
},
{
id: 18,
src: 'https://www.qianduange.cn/upload/article/img18.jpg'
},
{
id: 19,
src: 'https://www.qianduange.cn/upload/article/img19.jpg'
},
{
id: 20,
src: 'https://www.qianduange.cn/upload/article/img20.jpg'
},
{
id: 21,
src: 'https://www.qianduange.cn/upload/article/img21.jpg'
},
{
id: 22,
src: 'https://www.qianduange.cn/upload/article/img22.jpg'
},
{
id: 23,
src: 'https://www.qianduange.cn/upload/article/img23.jpg'
},
{
id: 24,
src: 'https://www.qianduange.cn/upload/article/img24.jpg'
},
{
id: 25,
src: 'https://www.qianduange.cn/upload/article/img25.jpg'
}
])
//获取接口数据
const getProduct = () => {
loading.value = true
productList.value = [...productList.value, ...arr]
}
const handleScroll = () => {
const scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight)
//滚动条滚动距离
const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
//窗口可视范围高度
const clientHeight =
window.innerHeight || Math.min(document.documentElement.clientHeight, document.body.clientHeight)
if ((clientHeight + scrollTop) + 100 >= scrollHeight) {
//快到底时----加载
getProduct()
}
}
const debounce = (fn, delay) => {
let timeout
return function () {
clearTimeout(timeout)
timeout = setTimeout(() => {
fn.apply(this, arguments)
}, delay)
}
}
onMounted(() => {
window.addEventListener('scroll', debounce(handleScroll, 1000))
})
</script>
<style lang="scss" scoped>
.loading-text {
text-align: center;
position: absolute;
left: 0;
right: 0;
z-index: 999;
margin: auto;
padding: 20px 0;
font-size: 16px;
}
:deep(.waterfall-list) {
background: none;
}
.container {
padding: 0 12px;
}
</style>