阿里巴巴官网首页网站,已备案域名购买网址低价,网站无法添加图片,松岗做网站瀑布流 - Vue3基于Grid布局简单实现一个瀑布流组件
前言
在学习Grid布局之时#xff0c;我发现其是CSS中的一种强大的布局方案#xff0c;它将网页划分成一个个网格#xff0c;可以任意组合不同的网格#xff0c;做出各种各样的布局#xff0c;在刷某书和某宝首页时我发现其是CSS中的一种强大的布局方案它将网页划分成一个个网格可以任意组合不同的网格做出各种各样的布局在刷某书和某宝首页时我们发现其展示方式就是一种瀑布流是一种流行的网站页面布局视觉表现为参差不齐的多栏布局随着页面向下滚动这种布局会不断加载数据块并附加到当前尾部。采用瀑布流布局的方式可以打破常规网站布局排版给用户眼前一亮的新鲜感更好的适应移动端。 因此结合二者本文将通过grid布局简单实现一个瀑布流组件该组件已开源上传npm可以直接安装使用Git地址在文尾。
实现原理
1、使用grid布局将页面分为无数个小网格每个网格高度为1px。
.grid-content {display: grid;grid-auto-rows: minmax(1px, 1px);overflow: auto;
}2、宽度根据需要自定义的列数自动分配。 grid-template-columns: repeat(${props.columns}, 1fr),3、根据每个卡片窗口的高度计算每个卡片需要跨越几个网格因为每个网格设置高为1px所以高度就是需要跨越的网格数
grid-row-end: span ${gridItem.value.clientHeight - 1}4、监听瀑布流滚动事件通过判断滚动条距离底部的高度在滚动到底部一定距离时加载更多的数据以实现无限滚动。
主要代码实现
gridContent 组件主要代码循环展示每个条目根据自定义的列展示不同的列数量根据触底数据判断获取最新数据。监听传入的数据进行处理目前只是做了简单处理后面将通过虚拟列表的形式动态处理该数据以增加性能。
templatediv classgrid-content refgridContent :stylegridStyle scrollgetMoreDatagrid-item v-foritem in showDataList :keyitem.dataIndex :dataitemtemplate #slot-scopeslotPropsslot nameslot-scope :slotPropsslotProps/slot/template/grid-item/div
/template
script langts setup
import GridItem from ./gridItem.vue;
import { ref, watch } from vue;const props defineProps({dataList: {type: Array,default: []},columns: {type: Number,default: 2},width: {type: Number,default: 300},height: {type: Number,default: 400},bottom:{type: Number,default: 50},loading:{type: Boolean,default: true}})const emitdefineEmits([getMoreData]);const gridStyle ref({});
const showDataList refany([])watch(() props.dataList, (newValue) {let tempData: any [];newValue.forEach((item: any, index) {tempData.push({ ...item, dataIndex: index })})showDataList.value tempData;gridStyle.value {grid-template-columns: repeat(${props.columns}, 1fr),width:props.width px,height:props.height px}
}, { immediate: true,deep:true })const isLoadingrefboolean(false);
watch(()props.loading,(newValue:boolean){isLoading.valuenewValue;
})const gridContentrefany(null);
//根据触底数据判断获取最新数据
const getMoreData(){const scrollHeight gridContent.value.scrollHeight || 0;const clientHeight gridContent.value.clientHeight || 0;const scrollTop gridContent.value.scrollTop || 0;if(scrollHeight - clientHeight - scrollTop props.bottom !isLoading.value){isLoading.valuetrue;emit(getMoreData);}
}
/scriptgrid-item 组件代码主要通过获取组件高度设置跨越的网格数,通过插槽展示每个卡片。
templatediv classgrid-item :styleitemStylediv refgridItemslot nameslot-scope :datadata/slot/div/div
/template
script langts setup
import { ref, onMounted } from vue;
defineProps({data: {type: Object,default: () { }}
})const gridItem refany(null);
const itemStyle ref({})onMounted(() {itemStyle.value { grid-row-end: span ${gridItem.value.clientHeight - 1} }
})/script
style scoped
.grid-item {grid-row-end: span 100;
}
/style
使用示例
npm install fcli/vue-grid-waterfall --save-dev 来安装在项目中使用
import VueGridWaterfall from fcli/vue-grid-waterfall;
const appcreateApp(App)
app.use(VueGridWaterfall);
示例 templatediv classcontentvue-grid-waterfall :data-listdataList :columns3 getMoreDatagetMoreData :loadingisLoadingtemplate #slot-scope{ slotProps }div classitem :style{ height: slotProps.data.height, background: slotProps.data.color }{{ slotProps.data.color}}/div/template/vue-grid-waterfall/div
/templatescript setup langts
import vueGridWaterfall from ./plugin/index.vue;
import { ref, onMounted } from vue
component: {vueGridWaterfall
}const dataList refany([]);
//获取随机颜色
const getRandomColor () {const getColor: any (color: any) {return (color 0123456789abcdef[Math.floor(Math.random() * 16)]) (color.length 6) ? color : getColor(color);};return # getColor()
}const getMoreData () {isLoading.value true;getData()
}
const isLoading ref(true);//获取数据
const getData () {for (let i 0; i 100; i) {dataList.value.push({ height: 50 Math.random() * 50 px, color: getRandomColor() })}setTimeout((){isLoading.value false;})
}onMounted(() {getData()
})
/script
属性属性名称类型可选值dataList瀑布流列表数据Array[]columns展示的列数number2width瀑布流宽度number0height瀑布流高度number0bottom滚动到底部触发加载数据的距离number50loading是否加在载数据boolean加载数据完数据设为false#slot-scope插槽objectslotProps.data
最后
本组件为初步实现后续还会结合虚拟滚动减少dom渲染当数据量过大时提升性能欢迎star关注。
Git地址https://gitee.com/fcli/vue-grid-waterfall.git