kl-waterfall 瀑布流
2021/10/7 23:14:04
本文主要是介绍kl-waterfall 瀑布流,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 使用
- 实现
- waterfall index文件
- kl-waterfall-item
使用
<kl-waterfall @touchBottom="touchBottom" :distant="50" :cope="4" :margin="10" :sleep="200" > <kl-waterfall-item v-for="(item, index) in state.imgs" :key="index" border> <div class="item"> <img :src="item.url" alt="" /> <p> {{ item.content }} </p> </div> </kl-waterfall-item> </kl-waterfall>
实现
waterfall index文件
<template> <div class="kl-waterfall" ref="waterRef"> <slot></slot> </div> </template> <script lang="ts" setup> import { onMounted, reactive, ref, onBeforeUpdate, onBeforeUnmount, } from "vue-demi"; import { throttle } from "../../utils/tool"; const props = defineProps({ cope: { // 份数 type: Number, default: 5, required: false, }, margin: { // 每份的间隔 type: Number, default: 10, required: false, }, sleep: { // 默认延时加载 建议图片越多,值越大 type: Number, default: 200, required: false, }, distant: { // 距离多远触底 就触发 触底回调 type: Number, default: 200, required: false, }, }); const emits = defineEmits(["touchBottom"]); const waterRef = ref(); interface i_state { childWidth: number; // 每项的公共宽度 heightArr: number[]; // 存储每列的高度数组 max: number; // 当前的最高项的高度 top: number; // 当前kl-waterfall 距离顶部的距离 clientHeight: number; // 可视区高度 isBottom: boolean; // 是否到了底部 lastLength: number; // 上次的长度 timer: any; // 记录timer } const state = reactive<i_state>({ childWidth: 0, heightArr: [], max: 0, top: 0, clientHeight: 0, isBottom: false, lastLength: 0, timer: null, }); // 滚动事件 const handleScroll = throttle(() => { //scrollTop就是触发滚轮事件时滚轮的高度 var scrollTop = document.documentElement.scrollTop || document.body.scrollTop; // console.log(scrollTop + state.clientHeight); if ( state.max + state.top <= scrollTop + state.clientHeight + props.distant && !state.isBottom ) { state.isBottom = true; emits("touchBottom", { code: 200, msg: "触底了", }); } }, 50); onMounted(() => { const width = waterRef.value.clientWidth; state.top = waterRef.value.offsetTop; state.clientHeight = document.documentElement.clientHeight; // 每个子元素的宽度 let childWidth = Math.ceil( (width - (props.cope + 1) * props.margin) / props.cope ); state.childWidth = childWidth; // 开始处理业务 handleEvent(); // 添加触底事件 window.addEventListener("scroll", handleScroll, true); }); onBeforeUnmount(() => { clearTimeout(state.timer); state.timer = null; }); // 具体处理相关的业务 function handleEvent() { // console.log(state.lastLength); clearTimeout(state.timer); state.timer = null; state.timer = setTimeout(() => { // 给每个子项设宽 let childs = waterRef.value.children; // console.log(childs.length); let childLength = childs.length; for (let i = state.lastLength; i < childLength; i++) { childs[i].style.width = state.childWidth + "px"; } state.isBottom = false; // 获取每个元素的高 for (let i = state.lastLength; i < childLength; i++) { let height: number = Number(childs[i].offsetHeight) || 0; // console.log(height); // 第一排设置 if (i < props.cope) { childs[i].style.top = props.margin + "px"; childs[i].style.left = (i + 1) * props.margin + i * state.childWidth + "px"; state.heightArr.push(props.margin + height); // console.log("kkk"); } else { // 找到最小项 let minHeight = Math.min(...state.heightArr); // 找到最小项的index let minHeightIndex = state.heightArr.findIndex((item) => { return item == minHeight; }); childs[i].style.top = state.heightArr[minHeightIndex] + props.margin + "px"; childs[i].style.left = (minHeightIndex + 1) * props.margin + minHeightIndex * state.childWidth + "px"; state.heightArr[minHeightIndex] = minHeight + props.margin + height; } } // 重新给父元素定高度 let max = Math.max(...state.heightArr); state.max = max; waterRef.value.style.height = max + props.margin + "px"; // 记录下当前的长度 state.lastLength = childLength; }, props.sleep); } // 当数据更新时的业务 onBeforeUpdate(() => { handleEvent(); }); </script> <style lang="scss" scoped> .kl-waterfall { display: block; position: relative; } .kl-loading { height: 50px; text-align: center; color: #666; } </style>
kl-waterfall-item
<template> <div :class="[ 'kl-clearFix', 'kl-waterfall-item', border ? 'kl-waterfall-item-border' : '', ]" > <slot /> </div> </template> <script lang="ts" setup> defineProps({ border: { type: Boolean, default: false, required: false, }, }); </script> <style lang="scss" scoped> .kl-waterfall-item-border { box-shadow: 0 0 5px #555; display: block; position: absolute; } </style>
这篇关于kl-waterfall 瀑布流的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-28MQ底层原理资料详解:新手入门教程
- 2024-11-28MQ项目开发资料详解:新手入门教程
- 2024-11-28MQ项目开发资料详解:入门与初级用户指南
- 2024-11-28MQ消息队列资料入门教程
- 2024-11-28MQ消息队列资料:新手入门详解
- 2024-11-28MQ消息中间件资料详解与应用教程
- 2024-11-28MQ消息中间件资料入门教程
- 2024-11-28MQ源码资料详解与入门教程
- 2024-11-28MQ源码资料入门教程
- 2024-11-28RocketMQ底层原理资料详解