当前位置: 首页 > 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}])
http://www.lryc.cn/news/521717.html

相关文章:

  • Android Room 持久化库的介绍及使用方法
  • Go语言中http.Transport的Keep-Alive配置与性能优化方法
  • 设计模式03:行为型设计模式之策略模式的使用情景及其基础Demo
  • C# 多线程 Task TPL任务并行
  • 【matlab】matlab知识点及HTTP、TCP通信
  • kalilinux - msf和永恒之蓝漏洞
  • 网络安全测评质量管理与标准解读
  • Cesium根据地图的缩放zoom实现不同级别下geojson行政边界的对应展示
  • Linux初识:【shell命令以及运行原理】【Linux权限的概念与权限管理】
  • 深入剖析 Wireshark:网络协议分析的得力工具
  • 【AIGC】SYNCAMMASTER:多视角多像机的视频生成
  • PyTorch框架——基于深度学习YOLOv5神经网络水果蔬菜检测识别系统
  • Redisson中红锁(RedLock)的实现
  • 小结:路由器和交换机的指令对比
  • 使用yarn命令创建Vue3项目
  • Three.js+Vue3+Vite应用lil-GUI调试开发3D效果(三)
  • K8S集群常用命令
  • 【优先算法】滑动窗口--(结合例题讲解解题思路)(C++)
  • mayavi -> python 3D可视化工具Mayavi的安装
  • 【C++】B2112 石头剪子布
  • 【Vue】vue3 video 保存视频进度,每次进入加载上次的视频进度
  • C# 25Dpoint
  • 如何制作一个高质量的 Dockerfile 镜像:从入门到实践
  • Linux 机器学习
  • 青少年编程与数学 02-006 前端开发框架VUE 25课题、UI数据
  • css实现响应式详解
  • python-应用自动化操作方法集合
  • mac地址是用来做什么的
  • 【Compose multiplatform教程】05 IOS环境编译
  • 3D滤波器处理遥感tif图像