vant
Version:
Mobile UI Components built on Vue
191 lines (164 loc) • 4.68 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _utils = require("../utils");
var _style = require("../utils/dom/style");
var _scroll = require("../utils/dom/scroll");
var _bindEvent = require("../mixins/bind-event");
var _loading = _interopRequireDefault(require("../loading"));
// Utils
// Mixins
// Components
var _createNamespace = (0, _utils.createNamespace)('list'),
createComponent = _createNamespace[0],
bem = _createNamespace[1],
t = _createNamespace[2];
var _default = createComponent({
mixins: [(0, _bindEvent.BindEventMixin)(function (bind) {
if (!this.scroller) {
this.scroller = (0, _scroll.getScroller)(this.$el);
}
bind(this.scroller, 'scroll', this.check);
})],
model: {
prop: 'loading'
},
props: {
error: Boolean,
loading: Boolean,
finished: Boolean,
errorText: String,
loadingText: String,
finishedText: String,
immediateCheck: {
type: Boolean,
default: true
},
offset: {
type: [Number, String],
default: 300
},
direction: {
type: String,
default: 'down'
}
},
data: function data() {
return {
// use sync innerLoading state to avoid repeated loading in some edge cases
innerLoading: this.loading
};
},
updated: function updated() {
this.innerLoading = this.loading;
},
mounted: function mounted() {
if (this.immediateCheck) {
this.check();
}
},
watch: {
loading: 'check',
finished: 'check'
},
methods: {
// @exposed-api
check: function check() {
var _this = this;
this.$nextTick(function () {
if (_this.innerLoading || _this.finished || _this.error) {
return;
}
var el = _this.$el,
scroller = _this.scroller,
offset = _this.offset,
direction = _this.direction;
var scrollerRect;
if (scroller.getBoundingClientRect) {
scrollerRect = scroller.getBoundingClientRect();
} else {
scrollerRect = {
top: 0,
bottom: scroller.innerHeight
};
}
var scrollerHeight = scrollerRect.bottom - scrollerRect.top;
/* istanbul ignore next */
if (!scrollerHeight || (0, _style.isHidden)(el)) {
return false;
}
var isReachEdge = false;
var placeholderRect = _this.$refs.placeholder.getBoundingClientRect();
if (direction === 'up') {
isReachEdge = scrollerRect.top - placeholderRect.top <= offset;
} else {
isReachEdge = placeholderRect.bottom - scrollerRect.bottom <= offset;
}
if (isReachEdge) {
_this.innerLoading = true;
_this.$emit('input', true);
_this.$emit('load');
}
});
},
clickErrorText: function clickErrorText() {
this.$emit('update:error', false);
this.check();
},
genLoading: function genLoading() {
var h = this.$createElement;
if (this.innerLoading && !this.finished) {
return h("div", {
"key": "loading",
"class": bem('loading')
}, [this.slots('loading') || h(_loading.default, {
"attrs": {
"size": "16"
}
}, [this.loadingText || t('loading')])]);
}
},
genFinishedText: function genFinishedText() {
var h = this.$createElement;
if (this.finished) {
var text = this.slots('finished') || this.finishedText;
if (text) {
return h("div", {
"class": bem('finished-text')
}, [text]);
}
}
},
genErrorText: function genErrorText() {
var h = this.$createElement;
if (this.error) {
var text = this.slots('error') || this.errorText;
if (text) {
return h("div", {
"on": {
"click": this.clickErrorText
},
"class": bem('error-text')
}, [text]);
}
}
}
},
render: function render() {
var h = arguments[0];
var Placeholder = h("div", {
"ref": "placeholder",
"key": "placeholder",
"class": bem('placeholder')
});
return h("div", {
"class": bem(),
"attrs": {
"role": "feed",
"aria-busy": this.innerLoading
}
}, [this.direction === 'down' ? this.slots() : Placeholder, this.genLoading(), this.genFinishedText(), this.genErrorText(), this.direction === 'up' ? this.slots() : Placeholder]);
}
});
exports.default = _default;