1、什么是瀑布流呢?

瀑布流,又称瀑布流式布局。是比较流行的一种网站页面布局,视觉表现为参差不齐的多栏布局,随着页面滚动条向下滚动,这种布局还会不断加载数据块并附加至当前尾部。

瀑布流对于图片的展现,是高效而具有吸引力的,用户一眼扫过的快速阅读模式可以在短时间内获得更多的信息量,而瀑布流里懒加载模式又避免了用户鼠标点击的翻页操作,瀑布流的主要特性便是错落有致,定宽而不定高的设计让页面区别于传统的矩阵式图片布局模式,巧妙的利用视觉层级,视线的任意流动又缓解了视觉疲劳,同时给人以不拘一格的感觉,切中年轻一族的个性化心理。

下面这些就是用瀑布流来实现,看起来是不是很美观呢?

2、实现一个简单的瀑布流

先看一下咱们最终的试下效果吧,只是简单传入文字进行演示

1、瀑布流的特点

1、琳琅满目:整版以图片为主,大小不一的图片按照一定的规律排列。

2、唯美:图片的风格以唯美的图片为主。

3、操作简单:在浏览网站的时候只需要轻轻滑动一下鼠标滚轮,一切的美妙的图片精彩便可呈现在你面前

2、核心算法

通过图片我们可以直观的看到,每一个卡片的高度都是不一样的,需要我们实时能计算高度,同时左右的高度还是不能相互影响。

这里我们主要通过两个数组进行实现,即分为左右数组,核心代码如下:

<view id="u-left-column" class="u-column">
<slot name="left" :leftList="leftList"></slot>
</view>
<view id="u-right-column" class="u-column">
<slot name="right" :rightList="rightList"></slot>
</view> data() {
return {
leftList: [],
rightList: [],
tempList: [],
scrollTop: 0,
}
}

对传入数组进行分组和计算高度

async splitData() {
if (!this.tempList.length) return;
let leftRect = await this.$uGetRect('#u-left-column');
let rightRect = await this.$uGetRect('#u-right-column');
// 如果左边小于或等于右边,就添加到左边,否则添加到右边
let item = this.tempList[0];
// 解决多次快速上拉后,可能数据会乱的问题,因为经过上面的两个await节点查询阻塞一定时间,加上后面的定时器干扰
// 数组可能变成[],导致此item值可能为undefined
if (!item) return;
if (leftRect.height < rightRect.height) {
this.leftList.push(item);
} else if (leftRect.height > rightRect.height) {
this.rightList.push(item);
} else {
// 这里是为了保证第一和第二张添加时,左右都能有内容
// 因为添加第一张,实际队列的高度可能还是0,这时需要根据队列元素长度判断下一个该放哪边
if (this.leftList.length <= this.rightList.length) {
this.leftList.push(item);
} else {
this.rightList.push(item);
}
}
// 移除临时列表的第一项
this.tempList.splice(0, 1);
// 如果临时数组还有数据,继续循环
if (this.tempList.length) {
this.splitData();
return
}
}

3、完整的组件代码如下

<template>
<scroll-view class="scroll-y" scroll-y="true" @scrolltolower="tolower" :scroll-top="scrollTop">
<view class="u-waterfall" id="list">
<view id="u-left-column" class="u-column">
<slot name="left" :leftList="leftList"></slot>
</view>
<view id="u-right-column" class="u-column">
<slot name="right" :rightList="rightList"></slot>
</view>
</view>
</scroll-view>
</template> <script>
export default {
name: "waterfall",
props: {
value: {
// 瀑布流数据
type: Array,
required: true,
default: function() {
return [];
}
},
scrolltolower: {
type: Function,
default: () => {}
}
},
data() {
return {
leftList: [],
rightList: [],
tempList: [],
scrollTop: 0,
}
},
watch: {
copyFlowList(nVal, oVal) {
this.tempList = this.cloneData(this.copyFlowList);
this.splitData();
}
},
mounted() {
this.tempList = this.cloneData(this.copyFlowList);
this.splitData();
// this.$on('clearWaterFall', this.clear)
},
computed: {
// 破坏flowList变量的引用,否则watch的结果新旧值是一样的
copyFlowList() {
return this.cloneData(this.value);
}
},
methods: {
async splitData() {
if (!this.tempList.length) return;
let leftRect = await this.$uGetRect('#u-left-column');
let rightRect = await this.$uGetRect('#u-right-column');
// 如果左边小于或等于右边,就添加到左边,否则添加到右边
let item = this.tempList[0];
// 解决多次快速上拉后,可能数据会乱的问题,因为经过上面的两个await节点查询阻塞一定时间,加上后面的定时器干扰
// 数组可能变成[],导致此item值可能为undefined
if (!item) return;
if (leftRect.height < rightRect.height) {
this.leftList.push(item);
} else if (leftRect.height > rightRect.height) {
this.rightList.push(item);
} else {
// 这里是为了保证第一和第二张添加时,左右都能有内容
// 因为添加第一张,实际队列的高度可能还是0,这时需要根据队列元素长度判断下一个该放哪边
if (this.leftList.length <= this.rightList.length) {
this.leftList.push(item);
} else {
this.rightList.push(item);
}
}
// 移除临时列表的第一项
this.tempList.splice(0, 1);
// 如果临时数组还有数据,继续循环
if (this.tempList.length) {
this.splitData();
return
}
},
// 复制而不是引用对象和数组
cloneData(data) {
return JSON.parse(JSON.stringify(data));
},
tolower(e) {
this.scrolltolower()
},
clear() {
this.leftList = []
this.rightList = []
}
}
}
</script> <style lang="scss" scoped>
@mixin vue-flex($direction: row) {
/* #ifndef APP-NVUE */
display: flex;
flex-direction: $direction;
/* #endif */
} .scroll-y {
height: 78vh;
margin-top: 18px;
} .u-waterfall {
@include vue-flex;
flex-direction: row;
align-items: flex-start;
} .u-column {
@include vue-flex;
flex: 1;
flex-direction: column;
height: auto;
width: 45vw;
word-break: break-all;
}
</style>

3、简单使用

基于vue的语法进行使用,先进行导入和注册

<script>
import waterfall from '../../component/waterfall/index.vue'
export default {
name: 'content',
components: {
waterfall
}
}
</script>

因为组件是基于插槽的形式进行开发的,所以我们可以直接传入咱们的样式和标签

<template>
<view class="main">
<waterfall :value="dataList" :scrolltolower="getRecommendLove" ref="child">
<template v-slot:left="left">
<view v-for="item in left.leftList" :key="item.id" class="left-content" @click="copy(item)">
<view class="item">
{{item.content}}
</view>
</view>
</template>
<template v-slot:right="right">
<view v-for="item in right.rightList" :key="item.id" class="right-content" @click="copy(item)">
<view class="item">
{{item.content}}
</view>
</view>
</template>
</waterfall>
</view>
</template>

最终的效果就可以达到我们的目标了

微信小程序实战,基于vue2实现瀑布流的更多相关文章

  1. [转]微信小程序之加载更多(分页加载)实例 —— 微信小程序实战系列(2)

    本文转自;http://blog.csdn.net/michael_ouyang/article/details/56846185 loadmore 加载更多(分页加载) 当用户打开一个页面时,假设后 ...

  2. WordPress 网站开发“微信小程序“实战(三)

    本文是"WordPress 开发微信小程序"系列的第三篇,本文记录的是开发"DeveWork+"小程序1.2 版本的过程.建议先看完第一篇.第二篇再来阅读本文. ...

  3. [转]微信小程序之购物车 —— 微信小程序实战商城系列(5)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70755892 续上一篇的文章:微信小程序之商品属性分类  —— 微信小程序实战商城 ...

  4. [转]微信小程序之购物数量加减 —— 微信小程序实战商城系列(3)

    本文转自:http://blog.csdn.net/michael_ouyang/article/details/70194144 我们在购买宝贝的时候,购物的数量,经常是我们需要使用的,如下所示: ...

  5. 【微信小程序】转载:微信小程序实战篇-下拉刷新与加载更多

    下拉刷新 实现下拉刷新目前能想到的有两种方式 1. 调用系统的API,系统有提供下拉刷新的API接口 当然,你可以直接在全局变量app.json的window里面配置上面这个属性,这样整个项目都允许下 ...

  6. 微信小程序实战篇:商品属性联动选择(案例)

    本期的微信小程序实战篇来做一个电商网站经常用到的-商品属性联动选择的效果,素材参考了一点点奶茶. 效果演示:   商品属性联动.gif 代码示例 1.commodity.xml <!-- < ...

  7. 微信小程序实战 购物车功能

    代码地址如下:http://www.demodashi.com/demo/12400.html 一.准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.com/ ...

  8. 微信小程序实战之天气预报

    原文:微信小程序实战之天气预报 这个案例是仿UC中天气界面做的中间也有点出入,预留了显示当前城市名字和刷新图标的位置,自己可以写下,也可以添加搜索城市.值得注意的是100%这个设置好像已经不好使了,可 ...

  9. 微信小程序实战之百思不得姐精简版

    原文:微信小程序实战之百思不得姐精简版 微信小程序基本组件和API已撸完,总归要回到正题的,花了大半天时间做了个精简版的百思不得姐,包括段子,图片,音频,视频,四个模块.这篇就带着大家简述下这个小的A ...

  10. 微信小程序实战篇:基于wxcharts.js绘制移动报表

    前言 微信小程序图表插件(wx-charts)是基于canvas绘制,体积小巧,支持图表类型饼图.线图.柱状图 .区域图等图表图形绘制,目前wx-charts是微信小程序图表插件中比较强大好使的一个. ...

随机推荐

  1. 【学习笔记】 第04章 NumPy基础:数组和矢量计算

    前言 正式开始学习Numpy,参考用书是<用Python进行数据清洗>,计划本周五之前把本书读完,关键代码全部实现一遍 NumPy基础:数组和矢量计算 按照书中所示,要搞明白具体的性能差距 ...

  2. K8s deployments的故障排查可视化指南已更新(2021 中文版)

    转载自:https://mp.weixin.qq.com/s/07S930e6vsN2iToo0gP0zg 英文版 高清图地址:https://learnk8s.io/a/a-visual-guide ...

  3. 使用k8s部署springcloud解决三大问题

    1.正式环境使用的话启动时需要指定使用正式的配置文件,这个要咋处理? 解决办法 文章地址:https://www.cnblogs.com/sanduzxcvbnm/p/13262411.html 分析 ...

  4. k3s部署全过程

    # 安装k3s博客 ## 准备工作 1.准备俩台可以相互访问的服务器 2.需要先安装dockers 3.以下教程将使用VsCode+ssh插件来进行插件图 ssh连接到俩台服务器 点击打开ssh操作界 ...

  5. ImGUI 1.87 绘制D3D外部菜单

    ImGUI 它是与平台无关的C++轻量级跨平台图形界面库,没有任何第三方依赖,可以将ImGUI的源码直接加到项目中使用,该框架通常会配合特定的D3Dx9等图形开发工具包一起使用,ImGUI常用来实现进 ...

  6. Leetcode刷题笔记(双指针)

    1.何为双指针 双指针主要用来遍历数组,两个指针指向不同的元素,从而协同完成任务.我们也可以类比这个概念,推广到多个数组的多个指针. 若两个指针指向同一数组,遍历方向相同且不会相交,可以称之为滑动窗口 ...

  7. C++ 栈和典型迷宫问题

    C++ 栈和迷宫问题 1. 前言 栈是一种受限的数据结构,要求在存储数据时遵循先进后出(Last In First Out)的原则.可以把栈看成只有一个口子的桶子,进和出都是走的这个口子(也称为栈顶) ...

  8. Hbase之命令

    Hbase之命令 -- 查询数据量 hbase org.apache.hadoop.hbase.mapreduce.RowCounter '{namespaceName:tablename}' cou ...

  9. MyBatis获取参数值的两种方式

    MyBatis获取参数值的两种方式:${}和#{} ${}的本质就是字符串拼接,#{}的本质就是占位符赋值 ${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单 ...

  10. .NET周报【10月第3期 2022-10-25】

    国内文章 聊一聊被 .NET程序员 遗忘的 COM 组件 https://www.cnblogs.com/huangxincheng/p/16799234.html 将Windows编程中经典的COM ...