vant PullRefresh组件分析

时间:2021-2-20 作者:admin

介绍

用于提供下拉刷新的交互操作。

分析

UML组件类图建模

注意:忽略了部分的属性和方法

布局

组件布局源代码:

render() {
    return (
      <div class="pull-refresh">
        <div ref="track" class="pull-refresh__track">
          <div class="pull-refresh__head">
            {this.genStatus()}
          </div>
          {this.slots()}
        </div>
      </div>
    );
  },

提示区域

.van-pull-refresh {
  &__head {
      // 下面只摘抄关键的
    position: absolute;
    left: 0;
    width: 100%;
    transform: translateY(-100%);
  }
}

逻辑实现

1.添加手势处理 TouchMixin

为滚动容器绑定手势事件,并计算相关的手势方向和滑动距离

export const TouchMixin = {
  data() {
    return { direction: '' };
  },

  methods: {
    touchStart(event) {
      this.resetTouchStatus();
      this.startX = event.touches[0].clientX;
      this.startY = event.touches[0].clientY;
    },

    touchMove(event) {
      const touch = event.touches[0];
      this.deltaX = touch.clientX - this.startX;
      this.deltaY = touch.clientY - this.startY;
      this.offsetX = Math.abs(this.deltaX);
      this.offsetY = Math.abs(this.deltaY);
      this.direction =
        this.direction || getDirection(this.offsetX, this.offsetY);
    },

    resetTouchStatus() {
      this.direction = '';
      this.deltaX = 0;
      this.deltaY = 0;
      this.offsetX = 0;
      this.offsetY = 0;
    },

    // avoid Vue 2.6 event bubble issues by manually binding events
    // https://github.com/youzan/vant/issues/3015
    bindTouchEvent(el) {
      const { onTouchStart, onTouchMove, onTouchEnd } = this;

      on(el, 'touchstart', onTouchStart);
      on(el, 'touchmove', onTouchMove);

      if (onTouchEnd) {
        on(el, 'touchend', onTouchEnd);
        on(el, 'touchcancel', onTouchEnd);
      }
    },
  },
};

2.组件内实现手势的事件处理逻辑

/*
* 只有核心逻辑
*/
methods: {
    onTouchStart (event) {

    },
    // 1. 调用touchMixin的手势计算
    // 2. 阻止事件默认行为和冒泡
    // 3. 对滑动的距离进行优化处理
    // 4. 根据距离,设置组件的状态
    onTouchMove (event) {
      this.touchMove(event);

      if (this.ceiling && this.deltaY >= 0 && this.direction === 'vertical') {
        preventDefault(event);
        this.setStatus(this.ease(this.deltaY));
      }
    },
    onTouchEnd (event) {
        this.$emit('refresh');
    }
}
声明:本文内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎进行举报,并提供相关证据,工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。