Vant 源码解析——IndexBar

本文详细解析了Vant组件库中IndexBar的实现原理,包括层级结构和核心滚动事件处理。同时,介绍了如何在IndexBar基础上扩展功能,实现类似微信通讯录的效果,包括吸顶、自定义样式和插槽等功能。文章还提供了实现这些特性的关键代码和注意事项。
摘要由CSDN通过智能技术生成

概述

本篇笔者来讲解一下 index-barindex-anchor 的实现原理和细节处理,以及结合实际场景会对其进行拓展,来实现Wechat通讯录相似的功能,保证让index-bar变得更加生动有趣,满足更多的业务场景。当然笔者会结合自身的理解,已经为每个核心的方法增加了必要的注释,会尽最大努力将其中的原理讲清楚,若有不妥之处,还望不吝赐教,欢迎批评指正。

预览

index-bar.gif

层级结构

index-bar :主要由 内容van-index-bar__sidebar组成,van-index-bar__sidebar 主要就是用来 点击或者触摸滑动 来滚动到指定的锚点(index-anchor).

index-anchor :主要由一个 div 包裹着一个 van-index-anchor,其中 van-index-anchor 如果 吸顶 了会变成 fixed 定位,以及包裹他的父元素( div )会设置高度,用于弥补其脱离文档流后的高度。

实现原理

笔者觉得 index-bar 中最核心的地方,在于滚动过程中,锚点的吸顶的处理。其中主要包括:获取哪个活跃的锚点将要吸顶,以及上一个活跃的锚点如何退场等。所以我们把核心点关注在:index-bar 所处的滚动容器 scroller 的滚动事件上。

mixins: [
  TouchMixin,
  ParentMixin('vanIndexBar'),
  BindEventMixin(function (bind) {
   
    // bind: on/off 函数
    if (!this.scroller) {
   
      this.scroller = getScroller(this.$el);
    }
    bind(this.scroller, 'scroll', this.onScroll);
  }),
],

onScroll() {
   
  if (isHidden(this.$el)) {
   
    return;
  }
  // 获取滚动容器的scrollTop
  const scrollTop = getScrollTop(this.scroller);
  // 返回滚动容器元素的大小及其相对于视口的位置 因为滚动容器可能不是 window/body,而且也有可能距离视口顶部有一段距离
  const scrollerRect = this.getScrollerRect();
  // 计算每一个锚点在滚动容器中的具体位置 top/height
  const rects = this.children.map((item) =>
    item.getRect(this.scroller, scrollerRect)
  );
  // 获取当前活跃的锚点
  const active = this.getActiveAnchorIndex(scrollTop, rects);

  this.activeAnchorIndex = this.indexList[active];

  if (this.sticky) {
   
    this.children.forEach((item, index) => {
   
      // 由于要设置 active 和 active-1 锚点的 fixed 属性,所以要把其,父容器的宽高 继承过来
      if (index === active || index === active - 1) {
   
        const rect = item.$el.getBoundingClientRect();
        item.left = rect.left;
        item.width = rect.width;
      } else {
   
        item.left = null;
        item.width = null;
      }

      // 核心代码
      if (index === active) {
   
        // 这里锚点已经是 fixed 定位
        item.active = true;
        
        // 计算top: 由于锚点 fixed 定位的 top为0,这里设置的top 是用于设置自身锚点的transform.y
        // rects[index].top 是相对于滚动容器的位置,是固定值
        // scrollTop: 是变量,向上滚动 增大, 向下滚动 减小
        item.top =
          Math.max(this.stickyOffsetTop
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值