captain-ui
Version:
有赞vue wap业务组件库
261 lines (227 loc) • 7.52 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.default = void 0;
var _scroll = _interopRequireDefault(require("../../../common/scroll"));
var _Nav = _interopRequireDefault(require("./components/Nav"));
var _Group = _interopRequireDefault(require("./components/Group"));
var _Coupon = _interopRequireDefault(require("./components/Coupon"));
var _config = _interopRequireDefault(require("./components/config"));
var _create = _interopRequireDefault(require("../utils/create"));
var _components;
var _default2 = (0, _create.default)({
render: function render() {
var _vm = this;
var _h = _vm.$createElement;
var _c = _vm._self._c || _h;
return _c('div', {
staticClass: "cap-taglist"
}, [_c('cap-taglist-nav', {
ref: "nav",
attrs: {
"tags": _vm.tags,
"active": _vm.active,
"nav-fixed": _vm.navFixed,
"window-height": _vm.windowHeight,
"page-position": _vm.pagePosition
},
on: {
"click": _vm.onClickBadge
}
}), _vm._l(_vm.tags, function (tag, index) {
return _c('cap-taglist-group', {
key: tag.alias,
attrs: {
"tag": tag,
"height": _vm.groupHeight[index],
"goods-list": _vm.goods[tag.alias] || [],
"loading-goods": _vm.loadingGoods,
"is-thumb-cover": _vm.isThumbCover
},
on: {
"load": function load($event) {
_vm.$emit('load', $event);
},
"click": _vm.onClickGoods
}
}, [index === 0 && _vm.showCoupons ? _c('div', {
staticClass: "cap-taglist__coupon--wrap",
attrs: {
"slot": "coupon"
},
slot: "coupon"
}, _vm._l(_vm.coupons, function (coupon) {
return _c('cap-taglist-coupon', {
key: coupon.id,
attrs: {
"coupon": coupon
}
});
}), 1) : _vm._e()]);
})], 2);
},
name: 'taglist',
components: (_components = {}, _components[_Nav.default.name] = _Nav.default, _components[_Group.default.name] = _Group.default, _components[_Coupon.default.name] = _Coupon.default, _components),
props: {
navFixed: Boolean,
tags: {
type: Array,
default: function _default() {
return [];
}
},
goods: {
type: Object,
default: function _default() {
return {};
}
},
preload: {
type: Number,
default: 1000
},
loadingGoods: {
type: Object,
default: function _default() {
return {};
}
},
imageFillStyle: {
type: [Number, String],
default: _config.default.IMAGE_FILL_STYLE.BLANK
},
coupons: {
type: Array,
default: function _default() {
return [];
}
}
},
data: function data() {
return {
active: 0,
groups: [],
lockActive: false,
pagePosition: 'above',
windowHeight: window.innerHeight
};
},
mounted: function mounted() {
this.scrollEl = _scroll.default.getScrollEventTarget(this.$el);
this.scrollEl.addEventListener('scroll', this.onScroll);
this.init();
},
destroyed: function destroyed() {
this.scrollEl.removeEventListener('scroll', this.onScroll);
},
watch: {
tags: function tags() {
this.init();
},
goods: function goods() {
this.init();
}
},
computed: {
groupHeight: function groupHeight() {
var _this = this;
var groupHeight = [];
this.tags.forEach(function (tag, index) {
var goodsList = _this.goods[tag.alias] || [];
var number = tag.number || goodsList.length;
groupHeight[index] = _config.default.TITLE_HEIGHT + (number ? _config.default.GOODS_HEIGHT * number : _config.default.EMEPTY_HEIGHT);
});
return groupHeight;
},
isThumbCover: function isThumbCover() {
return +this.imageFillStyle === _config.default.IMAGE_FILL_STYLE.COVER;
},
showCoupons: function showCoupons() {
return this.coupons.length > 0;
}
},
methods: {
init: function init() {
var _this2 = this;
this.$nextTick(function () {
_this2.getDOMHeight();
_this2.onScroll();
});
},
getDOMHeight: function getDOMHeight() {
this.elHeight = _scroll.default.getVisibleHeight(this.$el);
this.navHeight = _scroll.default.getVisibleHeight(this.$refs.nav.$el);
},
onScroll: function onScroll() {
var elHeight = this.elHeight,
navHeight = this.navHeight;
var elToTop = _scroll.default.getElementTop(this.$el);
var scrollTop = _scroll.default.getScrollTop(this.scrollEl);
var elToScrollElementDist = elToTop - _scroll.default.getElementTop(this.scrollEl) + scrollTop;
var pagePosition = 'contain';
if (elToScrollElementDist - scrollTop > 0) {
// Nav 未触顶
pagePosition = 'above';
} else if (scrollTop - elHeight + navHeight - elToScrollElementDist > 0) {
// Nav 触底
pagePosition = 'below';
}
this.pagePosition = pagePosition;
this.updateActive(scrollTop - elToScrollElementDist);
this.updateVisibleGroup(elToTop, scrollTop);
},
// 根据滚动条位置自动切换 active badge
updateActive: function updateActive(overscrollHeight) {
var _this3 = this;
if (this.lockActive) {
return;
}
var totalHeight = 0;
var activeIndex = -1;
this.tags.some(function (tag, index) {
totalHeight += _this3.groupHeight[index];
if (totalHeight > overscrollHeight) {
activeIndex = index;
return true;
}
});
this.active = activeIndex === -1 ? this.tags.length - 1 : activeIndex;
},
// 根据滚动条位置判断需要渲染的 group
updateVisibleGroup: function updateVisibleGroup(elToTop, scrollTop) {
var currentHeight = 0;
var preload = this.preload,
windowHeight = this.windowHeight,
groupHeight = this.groupHeight;
this.groups.forEach(function (group, index) {
var viewBot = scrollTop + windowHeight;
var nodeTop = currentHeight + elToTop;
var nodeBot = nodeTop + groupHeight[index];
group.visible = nodeBot >= scrollTop - preload && nodeTop <= viewBot + preload;
currentHeight += groupHeight[index];
});
},
onClickBadge: function onClickBadge(active) {
var _this4 = this;
// 点击左侧导航修改的情况下,禁止滚动导致左侧导航变化
this.active = active;
this.lockActive = true; // elToScrollElementDist: 元素上边沿和滚动元素上边沿的距离
var el = this.$el,
scrollEl = this.scrollEl;
var scrollTop = _scroll.default.getScrollTop(scrollEl);
var elToScrollElementDist = _scroll.default.getElementTop(el) - _scroll.default.getElementTop(scrollEl) + scrollTop; // 计算高亮
var ellipsisHeight = 0;
for (var i = 0; i < active; i++) {
ellipsisHeight += this.groupHeight[i];
} // 设置滚动高度
_scroll.default.setScrollTop(scrollEl, elToScrollElementDist + ellipsisHeight);
setTimeout(function () {
_this4.lockActive = false;
}, 200);
},
onClickGoods: function onClickGoods(goods, tag, index) {
this.$emit('click', goods, tag, index);
}
}
});
exports.default = _default2;