123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- // Utils
- import { createNamespace } from '../utils';
- import { isHidden } from '../utils/dom/style';
- import { getScroller } from '../utils/dom/scroll'; // Mixins
- import { BindEventMixin } from '../mixins/bind-event'; // Components
- import Loading from '../loading';
- var _createNamespace = createNamespace('list'),
- createComponent = _createNamespace[0],
- bem = _createNamespace[1],
- t = _createNamespace[2];
- export default createComponent({
- mixins: [BindEventMixin(function (bind) {
- if (!this.scroller) {
- this.scroller = 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 || 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, {
- "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]);
- }
- });
|