小程序瀑布流组件:支持翻页与图片懒加载

2020-11-06 导读

导读 : 最新精选区块链汽车创意科技媒体达人电影音乐娱乐休闲生活旅行学习工具历史读书金融理财美食菜谱小程序瀑布流组件:支持翻页与图片懒加载前端大全前端大全2020-05-30(给前端大全加星标,提升前端技能)作者:老人羽海https://segment...

导读 : 最新精选区块链汽车创意科技媒体达人电影音乐娱乐休闲生活旅行学习工具历史读书金融理财美食菜谱小程序瀑布流组件:支持翻页与图片懒加载前端大全前端大全2020-05-30(给前端大全加星标,提升前端技能)作者:老人羽海http...


小程序瀑布流组件:支持翻页与图片懒加载


  • 最新
  • 精选
  • 区块链
  • 汽车
  • 创意科技
  • 媒体达人
  • 电影音乐
  • 娱乐休闲
  • 生活旅行
  • 学习工具
  • 历史读书
  • 金融理财
  • 美食菜谱

小程序瀑布流组件:支持翻页与图片懒加载

前端大全 前端大全 2020-05-30

(给前端大全加星标,提升前端技能

作者:老人羽海

https://segmentfault.com/a/1190000022680541

电商小程序中,用到瀑布流的地方非常多,每次都写一个瀑布流,重复一次逻辑,作为程序员,肯定是非常不愿意的。


瀑布流的形式都是大同小异,不同的是瀑布流中每个模块的内容,随业务而变化。

所以,我们把瀑布流框架抽象成组件,瀑布流的内容由业务确定。这样即可实现组件化和自定义的最大平衡,微信小程序组件源码。


首先,我们来看一下瀑布流组件在实际项目中的实际效果。




1 实际效果


瀑布流组件实际效果如下图所示,左侧为用户交互效果,右侧为图片懒加载实际效果。



2 什么是瀑布流?


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


3 实现功能


该瀑布流组件实现了以下几个功能:


  • 支持图片懒加载
  • 支持上拉数据翻页
  • 支持自定义样式
  • 支持瀑布流Item间隔底层自动计算
  • 原生组件模式:即类swiper和swiper-item 组件用法
  • 组件与数据完全解耦



4 实现原理


4.1 waterfall 和waterfall-item实现原理


第一步:在 waterfall-layout 目录下创建 waterfall 和 waterfall-item 组件,目录结构如下:


.├── query-node.js├── waterfall-item.js├── waterfall-item.json├── waterfall-item.wxml├── waterfall-item.wxss├── waterfall.js├── waterfall.json├── waterfall.wxml└── waterfall.wxss


第二步:分别在waterfall.js 和 waterfall-item.js的relations选项中指定组件父、子级关系:


// waterfall.jsComponent({ // ... other code relations: { './waterfall-item': { type: 'child', }, // ... other code }})


// waterfall-item.jsComponent({ // ... other code relations: { '././waterfall': { type: 'parent', }, // ... other code }})


指定彼此的父、子组件的关系后,即可通过 this.getRelationNodes 原生 API,就能访问彼此实例对象及其属性和方法。


第三步:实现waterfall.wxml 和 waterfall-item.wxml代码:


waterfall.wxml代码实现非常简单,只有5行代码:


class="waterfall custom-class">
view class="waterfall-inner"> slot >slot> view>/view>


同样,waterfall-item.wxml代码实现也非常简单,只有5行代码:


class="waterfall-item custom-class" style="{{position}}:0;top:{{(top >= 0 ? top + 'px' : 0 + 'rpx')}};"> slot >slot>
/view>


不知道slot用法的童鞋,请参考微信小程序自定义组件模板和样式文档。


4.2 瀑布流原理


其实,不管是微信小程序、web、还是原生APP,瀑布流的实现原理都是一样的。都可以绝对定位和位置计算来实现。


瀑布流的大体过程如下图所示:


第一步:数据通过this.setData从逻辑层传输到视图层,进行第一渲染,由于每个waterfall-item 的top:0; 和 position:left;,所以都重叠了在一起。


第二步:通过节点查询API获取每个waterfall-item元素信息,并且计算出正确的top和position值。


第三步:setData每个waterfall-item的top和position,实现重排。



具体逻辑实现如下:


首先,我们来实现一个节点查询API querySelector,之后会用到:


// query-node.js/** * 获取当前页面中,选择器为 selector 的第一个node节点 * @param {String} selector 符合微信小程序规范的选择器 * @param {Object} context 调用环境,普通页面中为wx,自定义组件中为this;默认值为wx. * @return {Array} 返回一个数组,第一个元素为 node 节点 */export const querySelector = function (selector, context = wx) { return new Promise((resolve, reject) => { context.createSelectorQuery() .select(selector) .boundingClientRect((res) => { if (res) { resolve(res); } else { reject(`不存在选择器为 ${selector} 的节点`); } }) .exec(); })};


接着,看一下组件waterfall 和waterfall-item在实际项目中的用法:


waterfall loading="{{loadMorePending}}" isAllLoaded="{{isAllLoaded}}" > block wx:for="{{data.sections}}" wx:key="id" wx:for-item="product"> waterfall-item index="{{index}}" custom-class="flow-item-wrapper" > view class="product-item"> 业务代码 view>
waterfall-item> block> waterfall>


当第一个waterfall-item组件,在视图层布局完成后会执行ready生命周期钩子。


在 ready 生命周期钩子中,我们需要做两件事:


  • 获取父组件waterfall的实例对象,并挂载在waterfall-item组件的 this实例对象上。因为之后我们需要在waterfall-item组件中修改waterfall上的数据。
  • 获取waterfall-item组件的高度,计算waterfall-item组件的位置信息top和position。
// waterfall-item.jsimport { querySelector } from './query-node';Component({ // ... other code lifetimes: { ready() { const [waterfall] = this.getRelationNodes('./waterfall'); this.parent = waterfall; this.setWaterfallItemPosition(); }, } methods:{ async setWaterfallItemPosition() { querySelector('.waterfall-item', this) .then(async (node) => { const { top, position } = await this.parent.getWaterfallItemPostionInfo(node); this.setData({ top, position }) }) }, } // ... other code})


在setWaterfallItemPosition方法中,我们调用了父组件上的方法


this.parent.getWaterfallItemPostionInfo,获取当前waterfall-item组件的top和position信息。并把已经渲染好的waterfall-item组件的累计高度缓存在waterfall的leftHeights和rightHeights属性上,用于计算下一个waterfall-item组件位置,主要逻辑如下:

// waterfall.jsconst POSITION_LEFT = 'left';const POSITION_RIGHT = 'right';
Component({ // ... other code /** * 组件的方法列表 */ methods: { lifetimes: { ready() { this.initParams(); } }, initParams() { this.leftHeights = 0; this.rightHeights = 0; }, /** * 设置 waterfall-item 的高度值 * @param {Object} node waterfall-item 组件位置尺寸数据 */ async getWaterfallItemPostionInfo(node) { let top = 0; let position = POSITION_LEFT; const { height } = node; const { itemGap } = this; if (this.leftHeights this.rightHeights) { top = this.leftHeights; if(this.leftHeights === 0) { this.leftHeights += height; } else { top += itemGap; this.leftHeights += (height + itemGap); } } else { position = POSITION_RIGHT; top = this.rightHeights; if(this.rightHeights === 0) { this.rightHeights += height; } else { top += itemGap; this.rightHeights += (height + itemGap); } } return { top, position, } } // ... other code }})


当所有的waterfall-item重排结束后,瀑布流渲染完成。


4.3 图片懒加载原理


微信小程序中,标签本身是支持懒加载的,当lazy-load={{true}},且在即将进入一定范围(上下三屏)时才开始加载。


也就是说,当lazy-load={{true}},标签初次渲染在视口上下三屏之外时,是不会请求图片资源的,当即将进入三屏之内时,才会加载。


在4.2小节的图3中,的初始化位置设置成了top:0; 和 position:left;,所以,都在视口中。如果将top的值成三屏之外的数值,例如,400vh或者更大,则重排之后,任然在三屏之外的图片即会自动懒加载。


class="waterfall-item custom-class" style="{{position}}:0;top:{{(top >= 0 ? top + 'px' : itemCount * 100 + 'vh')}};"> slot >slot>
/view>


Component({ // waterfall-item.js // ... other code lifetimes: { ready() { const { itemCount } = this.data; const [waterfall] = this.getRelationNodes('./waterfall'); waterfall.childCount += 1; this.parent = waterfall; this.setData({ itemCount: itemCount + waterfall.childCount, }) }, }, // ... other code})


4.4 数据翻页


因为实现了wx:for 功能,和组件一样,因此翻页逻辑完全由用户自己定制,和只给你提供翻页的功能,组件就可以和瀑布流数据结构完全解耦。


4.5 瀑布流Item间隔底层自动计算


将列和行中,两个组件之间的距离定义为itemGap,则:


itemGap = waterfall宽度 - (waterfall-item宽度 * 2


在 的ready钩子中,可以获取到组件的宽度;同理,在的ready钩子中,可以获取到组件的宽度。
在调用getWaterfallItemPostionInfo之前,获取到itemGap的值即可。这样,在计算的top值时,除了第一行的的top值等于0之外,其他所有的top值等于:


// this.leftHeights += height + itemGap;// or// this.rightHeights += height + itemGap;


具体代码实现请查看源码




5 总结


通过瀑布流框架抽象,使和接近原生组件使用体验,同时使组件与数据完全解耦。通过巧妙的初始化位置top设置,使瀑布流具图片有懒加载的功能。





推荐阅读  点击标题可跳转

微前端在小米 CRM 系统的实践

前22年的Loser,后4年和自己赛跑的人 | 最惨前端面经

前端面试之 Vue 向技巧总结


觉得本文对你有帮助?请分享给更多人

关注「前端大全」加星标,提升前端技能

好文章,我在看❤️

    阅读原文

    前往看一看

    看一看入口已关闭

    在“设置”-“通用”-“发现页管理”打开“看一看”入口

    我知道了

    已发送

    发送到看一看

    发送中

    微信扫一扫
    使用小程序

    取消 允许

    取消 允许

    微信版本过低

    当前微信版本不支持该功能,请升级至最新版本。

    我知道了 前往更新

    确定删除回复吗?

    取消 删除

      知道了

      长按识别前往小程序

      本站仅按申请收录文章,版权归原作者所有
      如若侵权,请联系本站删除

      微信QQ空间新浪微博腾讯微博人人Twitter豆瓣百度贴吧

      觉得不错,分享给更多人看到

      前端大全 热门文章:

      不装逼地说,在 Google 到底能学到啥?    阅读/点赞 : 19171/143

      Vue 开源项目库汇总    阅读/点赞 : 19139/120

      小公司的前端应该怎么做?    阅读/点赞 : 16630/148

      趣图:调试 CSS 的感觉就是这样的    阅读/点赞 : 16480/105

      写给想成为前端工程师的同学们    阅读/点赞 : 15920/100

      纯CSS打造银色MacBook Air(完整版)    阅读/点赞 : 14555/138

      关于前端的思考与感悟    阅读/点赞 : 9017/150

      结合个人经历总结的前端入门方法    阅读/点赞 : 8750/297

      关于前端的思考与感悟    阅读/点赞 : 7250/142

      我做前端技术面试官的一些体会    阅读/点赞 : 6470/171

      前端大全 微信二维码

      前端大全 微信二维码

      前端大全 最新文章

      小程序瀑布流组件:支持翻页与图片懒加载  2020-05-30

      你们今年还敢和老板谈加薪吗?  2020-05-28

      微前端在小米 CRM 系统的实践  2020-05-28

      前22年的Loser,后4年和自己赛跑的人 | 最惨前端面经  2020-05-28

      前端面试之 Vue 向技巧总结  2020-05-27

      解读新一代 Web 性能体验和质量指标  2020-05-27

      Chrome DevTools中的这些骚操作,你都知道吗?  2020-05-26

      面向对象:带点文艺的理工女,寻找真诚上进的你  2020-05-26

      JSON.stringify() 的 5 个秘密特性  2020-05-24

      如何快速掌握前端三大件源码  2020-05-24

      (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); (function(){ var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?ba34c9f41d18b62312e960833b3cb4ae":"https://jspassport.ssl.qhimg.com/11.0.1.js?ba34c9f41d18b62312e960833b3cb4ae"; document.write(''); })();


      本站所收集的资源来源于互联网公开资料,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。本站部分作品是由网友自主投稿和发布,本站仅为交流平台,不为其版权负责。

      商务部:将研究制定商务领域支持粤港澳大湾区建设的政策措施
      打破“洋种子”垄断还需自身硬