dvant
Version: 
A Vue.js 2.0 Mobile UI at dawnwin modified from Youzan
142 lines (120 loc) • 4.53 kB
JavaScript
'use strict';
exports.__esModule = true;
var _utils = require('../utils');
var _scroll = require('../utils/scroll');
var _scroll2 = _interopRequireDefault(_scroll);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = (0, _utils.create)({
  render: function render() {
    var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('div', { staticClass: "van-pull-refresh" }, [_c('div', { staticClass: "van-pull-refresh__track", style: _vm.style, on: { "touchstart": _vm.onTouchStart, "touchmove": _vm.onTouchMove, "touchend": _vm.onTouchEnd, "touchcancel": _vm.onTouchEnd } }, [_c('div', { staticClass: "van-pull-refresh__head" }, [_vm.status === 'normal' ? _vm._t("normal") : _vm._e(), _vm.status === 'pulling' ? _vm._t("pulling", [_c('span', { staticClass: "van-pull-refresh__text" }, [_vm._v(_vm._s(_vm.pullingText || _vm.$t('pullingText')))])]) : _vm._e(), _vm.status === 'loosing' ? _vm._t("loosing", [_c('span', { staticClass: "van-pull-refresh__text" }, [_vm._v(_vm._s(_vm.loosingText || _vm.$t('loosingText')))])]) : _vm._e(), _vm.status === 'loading' ? _vm._t("loading", [_c('div', { staticClass: "van-pull-refresh__loading" }, [_c('loading'), _c('span', [_vm._v(_vm._s(_vm.loadingText || _vm.$t('loadingText')))])], 1)]) : _vm._e()], 2), _vm._t("default")], 2)]);
  },
  name: 'van-pull-refresh',
  props: {
    pullingText: String,
    loosingText: String,
    loadingText: String,
    value: {
      type: Boolean,
      required: true
    },
    animationDuration: {
      type: Number,
      default: 300
    },
    headHeight: {
      type: Number,
      default: 50
    }
  },
  data: function data() {
    return {
      status: 'normal',
      height: 0,
      duration: 0
    };
  },
  computed: {
    style: function style() {
      return {
        transition: this.duration + 'ms',
        transform: 'translate3d(0,' + this.height + 'px, 0)'
      };
    }
  },
  mounted: function mounted() {
    this.scrollEl = _scroll2.default.getScrollEventTarget(this.$el);
  },
  watch: {
    value: function value(val) {
      if (!val) {
        this.duration = this.animationDuration;
        this.getStatus(0);
      }
    }
  },
  methods: {
    onTouchStart: function onTouchStart(event) {
      if (this.status === 'loading') {
        return;
      }
      if (this.getCeiling()) {
        this.duration = 0;
        this.startX = event.touches[0].clientX;
        this.startY = event.touches[0].clientY;
      }
    },
    onTouchMove: function onTouchMove(event) {
      if (this.status === 'loading') {
        return;
      }
      this.deltaY = event.touches[0].clientY - this.startY;
      this.direction = this.getDirection(event.touches[0]);
      if (!this.ceiling && this.getCeiling()) {
        this.duration = 0;
        this.startY = event.touches[0].clientY;
        this.deltaY = 0;
      }
      if (this.ceiling && this.deltaY >= 0) {
        if (this.direction === 'vertical') {
          this.getStatus(this.ease(this.deltaY));
          event.preventDefault();
        }
      }
    },
    onTouchEnd: function onTouchEnd() {
      if (this.status === 'loading') {
        return;
      }
      if (this.ceiling && this.deltaY) {
        this.duration = this.animationDuration;
        if (this.status === 'loosing') {
          this.getStatus(this.headHeight, true);
          this.$emit('input', true);
          this.$emit('refresh');
        } else {
          this.getStatus(0);
        }
      }
    },
    getCeiling: function getCeiling() {
      this.ceiling = _scroll2.default.getScrollTop(this.scrollEl) === 0;
      return this.ceiling;
    },
    ease: function ease(height) {
      var headHeight = this.headHeight;
      return height < headHeight ? height : height < headHeight * 2 ? Math.round(headHeight + (height - headHeight) / 2) : Math.round(headHeight * 1.5 + (height - headHeight * 2) / 4);
    },
    getStatus: function getStatus(height, isLoading) {
      this.height = height;
      var status = isLoading ? 'loading' : height === 0 ? 'normal' : height < this.headHeight ? 'pulling' : 'loosing';
      if (status !== this.status) {
        this.status = status;
      }
    },
    getDirection: function getDirection(touch) {
      var distanceX = Math.abs(touch.clientX - this.startX);
      var distanceY = Math.abs(touch.clientY - this.startY);
      return distanceX > distanceY ? 'horizontal' : distanceX < distanceY ? 'vertical' : '';
    }
  }
});