当前位置: 首页 > news >正文

vue3 uniapp封装一个瀑布流组件


新增组件m-waterfall   这样就可以在页面直接使用 不用在引入了
<template><view class="m-waterfall"><view id="m-left-column" class="m-column"><slot name="left" :leftList="leftList"></slot></view><view id="m-right-column" class="m-column"><slot name="right" :rightList="rightList"></slot></view></view>
</template><script setup>
/*** @param value  瀑布流数据* @param addTime 插入数据的时间间隔* @param keyIdData / id值,用于清除某一条数据时,根据此idKey名称找到并移除*/import {computed,defineProps,toRefs} from "vue"const props=defineProps({// 瀑布流数据value: {required: true,type: Array,default: ()=>[]},// 每次向结构插入数据的时间间隔,间隔越长,越能保证两列高度相近,但是对用户体验越不好addTime: {type: [Number, String],default: 200},// id值,用于清除某一条数据时,根据此idKey名称找到并移除keyIdData: {type: String,default: 'id'}})const {value,addTime,keyIdData} = toRefs(props)const leftList = ref([])const rightList = ref([])const tempList = ref([])const pendingImages = ref(new Map()) // 用于追踪待加载的图片const copyFlowList= computed (()=> {return cloneData(value.value);})
// 记录正在加载的图片数量const loadingCount = ref(0)// 处理图片加载完成事件const preloadImage = async (item) => {return new Promise((resolve) => {if (!item.image) {resolve(item)return}// 如果这个图片已经在加载中,返回现有的 promiseif (pendingImages.value.has(item.image)) {return pendingImages.value.get(item.image)}const promise = new Promise((resolveImage) => {uni.getImageInfo({src: item.image,success: (res) => {// 保存图片的实际尺寸信息到 itemitem.imageWidth = res.widthitem.imageHeight = res.heightpendingImages.value.delete(item.image)resolveImage(item)},fail: () => {pendingImages.value.delete(item.image)resolveImage(item)}})})pendingImages.value.set(item.image, promise)resolve(promise)})}// const emit=defineEmits(['handleImageLoad'])watch(()=>value.value,(nVal,oVal)=>{let startIndex = Array.isArray(oVal) && oVal.length > 0 ? oVal.length : 0;tempList.value = tempList.value.concat(cloneData(nVal.slice(startIndex)));splitData();})onMounted(()=>{tempList.value = cloneData(copyFlowList.value);setTimeout(()=>{splitData();},200)})const instance = getCurrentInstance()const getColumnHeight = (columnId) => {return new Promise((resolve) => {uni.createSelectorQuery().in(instance).select(columnId).boundingClientRect(data => {resolve(data ? data.height : 0)}).exec()})}const splitData = async () => {if (tempList.value.length === 0) returnconst item = tempList.value[0]if (!item) returntry {// 等待图片预加载完成await preloadImage(item)// 获取两列的高度const [leftHeight, rightHeight] = await Promise.all([getColumnHeight('#m-left-column'),getColumnHeight('#m-right-column')])// 根据高度决定放入哪一列if (leftHeight <= rightHeight) {leftList.value.push(item)} else {rightList.value.push(item)}// 移除已处理的项目tempList.value.splice(0, 1)// 继续处理下一个项目if (tempList.value.length) {setTimeout(() => {splitData()}, Number(props.addTime))}} catch (error) {console.error('Error in splitData:', error)// 发生错误时也移除当前项目,继续处理下一个tempList.value.splice(0, 1)if (tempList.value.length) {splitData()}}}// 复制而不是引用对象和数组const cloneData=(data)=>{if(data){return JSON.parse(JSON.stringify(data));}else{return [];}}</script><style lang="scss" scoped>.m-waterfall {margin-top: 20rpx;display: flex;flex-direction: row;align-items: flex-start;gap: 10rpx;
}.m-column {display: flex;flex: 1;flex-direction: column;height: auto;
}.m-image {width: 100%;}
</style>

组件使用

<m-waterfall :value="product"><!-- 左边数据 --><template v-slot:left="{leftList}"><view @click="addDta" class="prodecutitem" v-for="(item,index) in leftList" :key="index"><view style="width: 100%;"><m-imgage :url="item.image"></m-imgage></view><view class="title">{{item.title}}</view><view class="desc">{{item.title}}</view></view></template><!-- 右边数据 --><template v-slot:right="{rightList}"><view class="prodecutitem" v-for="(item,index) in rightList" :key="index"><view><m-imgage :url="item.image"></m-imgage></view><view class="title">{{item.title}}</view><view class="desc">{{item.title}}</view></view></template></m-waterfal>数据const product=ref([{title:'水果蔬菜1',image:imgSrc.value},{title:'水果蔬菜2',image:"https://img2.baidu.com/it/u=3893165480,918722033&fm=253&fmt=auto&app=120&f=JPEG?w=729&h=1215"},{title:'水果蔬菜3',image:imgSrc.value},{title:'水果蔬菜1',image:imgSrc.value},{title:'水果蔬菜3',image:imgSrc.value}])

相关文章:

vue3 uniapp封装一个瀑布流组件

新增组件m-waterfall 这样就可以在页面直接使用 不用在引入了 <template><view class"m-waterfall"><view id"m-left-column" class"m-column"><slot name"left" :leftList"leftList"></slot&…...

Android Room 持久化库的介绍及使用方法

Android Room 是 Android Jetpack 组件之一&#xff0c;是 Google 官方推出的用于简化 SQLite 数据库操作的持久化库。它提供了一个抽象层&#xff0c;允许开发者在 SQLite 数据库上执行常见的 CRUD 操作&#xff0c;同时处理数据库连接、数据迁移和查询优化等底层细节。 Andr…...

Go语言中http.Transport的Keep-Alive配置与性能优化方法

在Go语言中&#xff0c;http.Transport是一个用于发送HTTP或HTTPS请求的客户端工具&#xff0c;它提供了许多可配置的参数以优化性能。其中&#xff0c;Keep-Alive配置是性能优化的关键部分。以下是对http.Transport的Keep-Alive配置与性能优化方法的详细解释&#xff1a; 一、…...

设计模式03:行为型设计模式之策略模式的使用情景及其基础Demo

1.策略模式 好处&#xff1a;动态切换算法或行为场景&#xff1a;实现同一功能用到不同的算法时和简单工厂对比&#xff1a;简单工厂是通过参数创建对象&#xff0c;调用同一个方法&#xff08;实现细节不同&#xff09;&#xff1b;策略模式是上下文切换对象&#xff0c;调用…...

C# 多线程 Task TPL任务并行

先总结一下 之前发展过程的要点 1&#xff1a; 为了保证多线程正确顺序执行 线程同步 2&#xff1a; 为了节省操作系统线程资源 线程池 异步 方式管理 正常来讲 使用这俩个要点 进行使用 多线程可以满足开发使用需求 但是 新的问题产生了 那就是 多个异步操作 需要编写大量的代…...

【matlab】matlab知识点及HTTP、TCP通信

1、矩阵运算 点乘&#xff1a;对于两个同维度的向量&#xff0c;点乘结果是这两个向量对应分量的乘积之和。 点除&#xff1a;是指对两个数组的对应元素进行除法运算。 点幂&#xff1a;表示元素对元素的幂运算。 >> A[1,2,3;4,5,6]; B[1,1,1;2,2,2]>> D1B.*AD…...

kalilinux - msf和永恒之蓝漏洞

Kali最强渗透工具 - metasploit metasploit是什么&#xff1f; msf是一款开源安全漏洞利用和测试工具&#xff0c;集成了各种平台上常见的溢出漏洞和流行的sheelcode&#xff0c;并持续保持更新。 具体操作 1、先切换到root用户&#xff0c;使用msfdb init命令初始化metaspl…...

网络安全测评质量管理与标准解读

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 注意说明 刚开始写过一些比较专业的分享&#xff0c;较多粉丝反应看不懂&#xff0c;本次通过大众的通俗易懂的词汇先了解概念然后再分享规范和详细的技术原理 一、网络安全测评质量管理 网络安全测…...

Cesium根据地图的缩放zoom实现不同级别下geojson行政边界的对应展示

实现效果&#xff1a; 随着地图的缩放&#xff0c;展示对应缩放级别下的行政边界。 准备数据&#xff1a; 1.国家行政边界数据 &#xff08;country.json&#xff09; 2.省级行政边界数据 &#xff08;province.json&#xff09; 3.市级行政边界数据&#xff08;city.json&…...

Linux初识:【shell命令以及运行原理】【Linux权限的概念与权限管理】

目录 一.shell命令以及运行原理 二.Linux权限的概念与权限管理 2.1Linux权限的概念 sudo普通用户提权 2.2Linux权限管理 2.2.1文件访问者的分类&#xff08;人&#xff09; 2.2.2文件类型和访问权限&#xff08;事物属性&#xff09; 2.2.3文件权限值的表示方法 字符…...

深入剖析 Wireshark:网络协议分析的得力工具

在网络技术的广阔领域中&#xff0c;网络协议分析是保障网络正常运行、优化网络性能以及进行网络安全防护的关键环节。而 Wireshark 作为一款开源且功能强大的网络协议分析工具&#xff0c;在网络工程师、安全专家以及网络技术爱好者中广受欢迎。本文将深入介绍 Wireshark 的功…...

【AIGC】SYNCAMMASTER:多视角多像机的视频生成

标题&#xff1a;SYNCAMMASTER: SYNCHRONIZING MULTI-CAMERA VIDEO GENERATION FROM DIVERSE VIEWPOINTS 主页&#xff1a;https://jianhongbai.github.io/SynCamMaster/ 代码&#xff1a;https://github.com/KwaiVGI/SynCamMaster 文章目录 摘要一、引言二、使用步骤2.1 TextT…...

PyTorch框架——基于深度学习YOLOv5神经网络水果蔬菜检测识别系统

基于深度学习YOLOv5神经网络水果蔬菜检测识别系统&#xff0c;其能识别的水果蔬菜有15种&#xff0c;# 水果的种类 names: [黑葡萄, 绿葡萄, 樱桃, 西瓜, 龙眼, 香蕉, 芒果, 菠萝, 柚子, 草莓, 苹果, 柑橘, 火龙果, 梨子, 花生, 黄瓜, 土豆, 大蒜, 茄子, 白萝卜, 辣椒, 胡萝卜,…...

Redisson中红锁(RedLock)的实现

一、什么是红锁 当在单点redis中实现redis锁时&#xff0c;一旦redis服务器宕机&#xff0c;则无法进行锁操作。因此会考虑将redis配置为主从结 构&#xff0c;但在主从结构中&#xff0c;数据复制是异步实现的。假设在主从结构中&#xff0c;master会异步将数据复制到slave中…...

小结:路由器和交换机的指令对比

路由器和交换机的指令有一定的相似性&#xff0c;但也有明显的区别。以下是两者指令的对比和主要差异&#xff1a; 相似之处 基本操作 两者都支持类似的基本管理命令&#xff0c;比如&#xff1a; 进入系统视图&#xff1a;system-view查看当前配置&#xff1a;display current…...

使用yarn命令创建Vue3项目

文章目录 1.技术栈2.创建流程2.1创建vue3项目2.2选择配置项2.3进入项目目录 3.使用Yarn启动项目3.1安装依赖3.2运行项目 1.技术栈 yarnvitevue3 2.创建流程 2.1创建vue3项目 vue create 项目名称2.2选择配置项 直接回车可选择Vue3 2.3进入项目目录 cd 项目名称默认在当前…...

Three.js+Vue3+Vite应用lil-GUI调试开发3D效果(三)

前期文章中我们完成了创建第一个场景、添加轨道控制器的功能&#xff0c;接下来我们继续阐述其他的功能&#xff0c;本篇文章中主要讲述如何应用lil-GUI调试开发3D效果&#xff0c;在开始具体流程和步骤之前&#xff0c;请先查看之前的内容&#xff0c;因为该功能必须在前期内容…...

K8S集群常用命令

1&#xff0c;查看pod kubectl get pods -A 查看所有的pod kubectl get pods 这个只查看namespace为default下的pod&#xff0c;也就是只查看默认命名空间下的pod kubectl get pod -A -o wide 查看所有的pod&#xff0c;并且放出的信息更全&#xff08;包含了pod的ip&#xff0…...

【优先算法】滑动窗口--(结合例题讲解解题思路)(C++)

目录 1. 例题1&#xff1a;最大连续1的个数 1.1 解题思路 1.2代码实现 1.3 错误示范如下&#xff1a;我最开始写了一种&#xff0c;但是解答错误&#xff0c;请看&#xff0c;给大家做个参考 2. 将 x 减到 0 的最小操作数 2.1解题思路 2.2代码实现 1. 例题1&#xff…...

mayavi -> python 3D可视化工具Mayavi的安装

前言 Mayavi是一个基于VTK&#xff08;Visualization Toolkit&#xff09;的科学计算和可视化工具&#xff0c;主要用于数据可视化和科学计算领域。 它提供了一系列的高级可视化工具&#xff0c;包括2D和3D图形、表面和体积渲染、流场可视化等。Mayavi可以通过Python脚本进行调…...

突破网盘限制的高效工具:解锁全速下载与无缝分享的实战指南

突破网盘限制的高效工具&#xff1a;解锁全速下载与无缝分享的实战指南 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 &#xff0c;支持 百度网盘 / 阿里云盘 / 中国移动云盘 /…...

BACnet4j实战:从模拟设备到点位数据采集的完整流程解析

1. BACnet4j与工业物联网数据采集入门 第一次接触BACnet协议时&#xff0c;我被各种专业术语搞得晕头转向。直到用BACnet4j成功读取到第一个温度传感器的数据&#xff0c;才真正理解这个协议的价值。BACnet/IP就像工业设备间的普通话&#xff0c;而BACnet4j就是让Java程序能说这…...

Magma智能剪辑系统:视频自动生成实战

Magma智能剪辑系统&#xff1a;视频自动生成实战 1. 引言 想象一下这样的场景&#xff1a;你有一个精彩的视频创意&#xff0c;写好了详细的脚本&#xff0c;但面对一堆零散的素材片段却无从下手。传统的视频剪辑需要逐帧挑选、拼接、添加转场&#xff0c;一个几分钟的视频可…...

OpenClaw 深度研究报告:从开源框架到企业级智能体平台的演进之路

一、核心定位&#xff1a;突破"对话天花板"的执行中枢 OpenClaw&#xff08;外号"龙虾"&#xff09; 是由奥地利工程师 Peter Steinberger 于 2025 年底开发的本地优先、模型无关的 AI 智能体运行框架。其核心价值主张极为鲜明&#xff1a; “The AI that …...

ROS实战:5分钟搞定大华网络摄像机RTSP流接入(Ubuntu18.04+Melodic版)

ROS实战&#xff1a;5分钟搞定大华网络摄像机RTSP流接入&#xff08;Ubuntu18.04Melodic版&#xff09; 在智能机器人开发领域&#xff0c;实时视频流处理是构建环境感知系统的核心能力之一。大华作为安防行业领先品牌&#xff0c;其网络摄像机被广泛应用于工业检测、智能巡检等…...

KEPServerEX与SQLServer数据库的无缝集成指南

1. KEPServerEX与SQLServer集成的核心价值 在工业自动化和数据采集领域&#xff0c;KEPServerEX作为领先的通信平台&#xff0c;与SQLServer数据库的集成能够实现设备数据到关系型数据库的高效流转。这种组合特别适合需要长期存储设备运行数据、生成生产报表或进行数据分析的场…...

抖音无水印下载完全指南:5分钟掌握批量下载核心技巧

抖音无水印下载完全指南&#xff1a;5分钟掌握批量下载核心技巧 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support…...

Pixel Couplet Gen部署案例:混合云架构(公有云API+私有云模型)方案

Pixel Couplet Gen部署案例&#xff1a;混合云架构&#xff08;公有云API私有云模型&#xff09;方案 1. 项目背景与价值 Pixel Couplet Gen是一款融合传统春节文化与现代像素艺术风格的AI春联生成器。该项目基于ModelScope大模型驱动&#xff0c;通过创新的8-bit像素游戏UI设…...

聊聊 Comsol 仿真方形锂离子电池那些事儿

comsol仿真 锂离子电池 电化学 仿真 comsol 方形锂离子电池的三维模型&#xff1a;三维模型有助于准确的评估电芯中的集流体和极耳等对电流、电位以及产热分布的影响。 模型基于三维 Newman 模型&#xff0c;其中包括了在颗粒尺度描述锂粒子插层和扩散的额外维度。 此外&#…...

intv_ai_mk11部署教程:supervisorctl status/restart/log三命令掌握服务运维全链路

intv_ai_mk11部署教程&#xff1a;supervisorctl status/restart/log三命令掌握服务运维全链路 1. 服务概述与核心功能 intv_ai_mk11是一款基于Llama架构的AI对话机器人&#xff08;7B参数&#xff09;&#xff0c;部署在GPU服务器上&#xff0c;能够提供智能对话服务。这个A…...