Heim >Web-Frontend >View.js >Führen Sie Sie Schritt für Schritt durch die Implementierung eines horizontalen Wasserfall-Flow-Plug-Ins mit Vue
Wie verwende ich Vue, um ein horizontales Wasserfall-Flow-Plug-in für Bilder zu implementieren? Hier möchte ich einige im Internet zusammengefasste Erkenntnisse mit Ihnen teilen und hoffe, dass sie Ihnen weiterhelfen.
Heute bin ich auf eine Anforderung gestoßen, die das Laden einiger Bilder in einem horizontalen Wasserfallfluss auf der Seite erfordert. Das hat mich plötzlich an etwas erinnert, das ich vor langer Zeit geschrieben habe „JS Zwei Möglichkeiten zur Implementierung des horizontalen Wasserfall-Flow-Layouts
Aber es gibt ein Problem für das Vue-Projekt, daher werde ich hier meinen Entwicklungsprozess nicht mitteilen Das Projekt verwendet für die Entwicklung das vorherige Back-End-Framework „Lernen Sie das CRMEB“, die Benutzeroberfläche verwendet iView-UI und die restlichen Szenarien stimmen mit anderen Vue-Projekten überein. [Verwandte Empfehlungen:vuejs Video-Tutorial]
Wenn es sich nicht um eine Vue-Umgebung handelt, ist unsere Logik
1.获取所有的p元素 2.获取盒子的宽度,宽度都是相同,高度不同 3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定 4.获取屏幕宽度 5.求出列数,屏幕宽度 / 盒子宽度 取整 6.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度 7.循环遍历所有的盒子,通过列数找到第一行所有的盒子,将第一行盒子的高度放入数组,再取出数组中最小的一个的下标,就是第6步思路的第一行盒子中最矮盒子的下标。 8.循环继续,第二行第一个盒子,通过绝对定位,放进页面。 9.关键,需要将数组中最小的值加上放进的盒子的高度 10.继续循环,遍历所有 11.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示
Aber wenn es ein Vue-Projekt ist, können wir es Reduzieren Sie die Logik auf die folgenden Schritte:
1.获取屏幕宽度 2..获取盒子的宽度,宽度都是相同,高度不同 3.在浮动布局中每一行的盒子个数不固定,是根据屏幕宽度和盒子宽度决定 4.求出列数,屏幕宽度 / 盒子宽度 取整 5.瀑布流最关键的是第二行的盒子的排布方式,通过获取第一行盒子中最矮的一个的下标,绝对定位,top是最矮盒子的高度,left是最矮盒子的下标 * 盒子的宽度 6.继续循环,遍历所有 7.如果想要加载更多,需要判断最后一个盒子的高度和页面滚动的距离,再将数据通过创建元素,追加进页面,再通过瀑布流布局展示
<template> <div class="tab-container" id="tabContainer"> <div class="tab-item" v-for="(item, index) in pbList" :key="index"> <img :src="item.url" /> </div> </div> </template> <style scoped> * { margin: 0; padding: 0; } /* 最外层大盒子 */ .tab-container { padding-top: 20px; position: relative; } /* 每个小盒子 */ .tab-container .tab-item { position: absolute; height: auto; border: 1px solid #ccc; box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04); background: white; /* 元素不能中断显示 */ break-inside: avoid; text-align: center; } .tab-container .tab-item img { width: 100%; height: auto; display: block; } </style>
Der Kern-JS-Teil
<script> export default { name:'compList', props:{ pbList:{ type:Array, default:()=>{return []} } }, data() { return { }; }, mounted() { this.$nextTick(()=>{ this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流 }) }, methods: { waterFall( wrapIdName, contentIdName, columns = 5, columnGap = 20, rowGap = 20 ) { // 获得内容可用宽度(去除滚动条宽度) const wrapContentWidth = document.querySelector(wrapIdName).offsetWidth; // 间隔空白区域 const whiteArea = (columns - 1) * columnGap; // 得到每列宽度(也即每项内容宽度) const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns); // 得到内容项集合 const contentList = document.querySelectorAll(contentIdName); // 成行内容项高度集合 const lineConentHeightList = []; for (let i = 0; i < contentList.length; i++) { // 动态设置内容项宽度 contentList[i].style.width = contentWidth + "px"; // 获取内容项高度 const height = contentList[i].clientHeight; if (i < columns) { // 第一行按序布局 contentList[i].style.top = "0px"; contentList[i].style.left = contentWidth * i + columnGap * i + "px"; // 将行高push到数组 lineConentHeightList.push(height); } else { // 其他行 // 获取数组最小的高度 和 对应索引 let minHeight = Math.min(...lineConentHeightList); let index = lineConentHeightList.findIndex( (listH) => listH === minHeight ); contentList[i].style.top = minHeight + rowGap +"px"; contentList[i].style.left = (contentWidth + columnGap) * index + "px"; // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距 lineConentHeightList[index] += height + rowGap; } } }, }, }; </script>
5. Verwendung der äußeren Ebene und verzögertes Laden<script> export default { name:'compList', props:{ pbList:{ type:Array, default:()=>{return []} } }, data() { return { }; }, mounted() { this.$nextTick(()=>{ this.waterFall("#tabContainer", ".tab-item"); //实现瀑布流 }) }, methods: { waterFall( wrapIdName, contentIdName, columns = 5, columnGap = 20, rowGap = 20 ) { // 获得内容可用宽度(去除滚动条宽度) const wrapContentWidth = document.querySelector(wrapIdName).offsetWidth; // 间隔空白区域 const whiteArea = (columns - 1) * columnGap; // 得到每列宽度(也即每项内容宽度) const contentWidth = parseInt((wrapContentWidth - whiteArea) / columns); // 得到内容项集合 const contentList = document.querySelectorAll(contentIdName); // 成行内容项高度集合 const lineConentHeightList = []; for (let i = 0; i < contentList.length; i++) { // 动态设置内容项宽度 contentList[i].style.width = contentWidth + "px"; // 获取内容项高度 const height = contentList[i].clientHeight; if (i < columns) { // 第一行按序布局 contentList[i].style.top = "0px"; contentList[i].style.left = contentWidth * i + columnGap * i + "px"; // 将行高push到数组 lineConentHeightList.push(height); } else { // 其他行 // 获取数组最小的高度 和 对应索引 let minHeight = Math.min(...lineConentHeightList); let index = lineConentHeightList.findIndex( (listH) => listH === minHeight ); contentList[i].style.top = minHeight + rowGap +"px"; contentList[i].style.left = (contentWidth + columnGap) * index + "px"; // 修改最小列的高度 最小列的高度 = 当前自己的高度 + 拼接过来的高度 + 行间距 lineConentHeightList[index] += height + rowGap; } } }, }, }; </script>
Bei der Verwendung dieses Plug-Ins gibt es aufgrund der inneren Ebene zwei Probleme Es ist Position: Absolut; Positionierung, wodurch das äußere P nicht geöffnet wird, was dazu führt, dass das äußere Boxmodell schlecht angeordnet ist , und die Seite wird langsam heruntergezogen und geladen. Was sollen wir also tun?
Hier gebe ich meine Verarbeitungsmethode an
Der Gesamtcode lautet wie folgt: <template>
<div>
<div class="list-box" @scroll="scrollFun">
<compList :pbList="pbList" ref="compList"></compList>
</div>
</div>
</template>
<script>
import compList from "@/pages/test/components/compList";
export default {
name:'testList',
components:{
compList
},
data() {
return {
//瀑布流数据
pbList: [
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
}
],
addList:[
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg3.doubanio.com%2Fview%2Fphoto%2Fm%2Fpublic%2Fp2650049201.jpg&refer=http%3A%2F%2Fimg3.doubanio.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1664935370&t=d4bf3e4d352c277a1bdebfcc8fda959f",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
},
{
url: "https://img1.baidu.com/it/u=2911909188,130959360&fm=253&fmt=auto&app=138&f=JPEG?w=440&h=641",
}
],
bottomMain:true
};
},
methods:{
scrollFun(e) {
const offsetHeight= e.target.offsetHeight
const scrollHeight= e.target.scrollHeight
const scrollTop= e.target.scrollTop
if((scrollHeight - (offsetHeight+scrollTop)) < 10){
if(this.bottomMain){
this.bottomMain = false
this.addListDataFun()
}
}
},
addListDataFun(){
this.$Spin.show({
render: (h) => {
return h('div', [
h('Icon', {
'class': 'demo-spin-icon-load',
props: {
type: 'ios-loading',
size: 18
}
}),
h('div', '数据更新中...')
])
}
});
setTimeout(() => {
this.pbList = this.pbList.concat(this.addList)
this.bottomMain = true
this.$nextTick(()=>{
this.$refs.compList.waterFall("#tabContainer", ".tab-item")
this.$Spin.hide()
})
},1000)
}
}
};
</script>
<style scoped>
.list-box{
position: relative;
width: 100%;
height: calc(100vh - 240px);
background: white;
padding: 20px 30px 20px 20px;
margin-top: 20px;
box-sizing: border-box;
overflow: auto;
}
</style>
scrollFun(e) { const offsetHeight= e.target.offsetHeight const scrollHeight= e.target.scrollHeight const scrollTop= e.target.scrollTop if((scrollHeight - (offsetHeight+scrollTop)) < 10){ if(this.bottomMain){ this.bottomMain = false this.addListDataFun() } } }, addListDataFun(){ this.$Spin.show({ render: (h) => { return h('div', [ h('Icon', { 'class': 'demo-spin-icon-load', props: { type: 'ios-loading', size: 18 } }), h('div', '数据更新中...') ]) } }); setTimeout(() => { this.pbList = this.pbList.concat(this.addList) this.bottomMain = true this.$nextTick(()=>{ this.$refs.compList.waterFall("#tabContainer", ".tab-item") this.$Spin.hide() }) },1000) }
)
Das obige ist der detaillierte Inhalt vonFühren Sie Sie Schritt für Schritt durch die Implementierung eines horizontalen Wasserfall-Flow-Plug-Ins mit Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!