UNPKG

dvant

Version:

A Vue.js 2.0 Mobile UI at dawnwin modified from Youzan

221 lines (181 loc) 6.15 kB
'use strict'; exports.__esModule = true; var _utils = require('../utils'); var _raf = require('../utils/raf'); var _event = require('../utils/event'); var _node = require('../utils/node'); var _node2 = _interopRequireDefault(_node); 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-tabs", class: "van-tabs--" + _vm.type }, [_c('div', { ref: "wrap", staticClass: "van-tabs__wrap", class: ["van-tabs__wrap--" + _vm.position, { 'van-tabs--scrollable': _vm.scrollable, 'van-hairline--top-bottom': _vm.type === 'line' }] }, [_c('div', { ref: "nav", staticClass: "van-tabs__nav", class: "van-tabs__nav--" + _vm.type }, [_vm.type === 'line' ? _c('div', { staticClass: "van-tabs__nav-bar", style: _vm.navBarStyle }) : _vm._e(), _vm._l(_vm.tabs, function (tab, index) { return _c('div', { key: index, ref: "tabs", refInFor: true, staticClass: "van-tab", class: { 'van-tab--active': index === _vm.curActive, 'van-tab--disabled': tab.disabled }, on: { "click": function click($event) { _vm.onClick(index); } } }, [tab.$slots.title ? _c('van-node', { attrs: { "node": tab.$slots.title } }) : _c('span', { staticClass: "van-ellipsis" }, [_vm._v(_vm._s(tab.title))])], 1); })], 2)]), _c('div', { staticClass: "van-tabs__content" }, [_vm._t("default")], 2)]); }, name: 'van-tabs', components: { VanNode: _node2.default }, props: { sticky: Boolean, active: { type: [Number, String], default: 0 }, type: { type: String, default: 'line' }, duration: { type: Number, default: 0.2 }, swipeThreshold: { type: Number, default: 4 } }, data: function data() { return { tabs: [], position: 'content-top', curActive: 0, navBarStyle: {} }; }, computed: { // whether the nav is scrollable scrollable: function scrollable() { return this.tabs.length > this.swipeThreshold; } }, watch: { active: function active(val) { this.correctActive(val); }, tabs: function tabs(_tabs) { this.correctActive(this.curActive || this.active); this.setNavBar(); }, curActive: function curActive() { this.scrollIntoView(); this.setNavBar(); // scroll to correct position if (this.position === 'page-top' || this.position === 'content-bottom') { _scroll2.default.setScrollTop(this.scrollEl, _scroll2.default.getElementTop(this.$el)); } }, sticky: function sticky(isSticky) { this.scrollHandler(isSticky); } }, mounted: function mounted() { var _this = this; this.correctActive(this.active); this.setNavBar(); this.$nextTick(function () { if (_this.sticky) { _this.scrollHandler(true); } _this.scrollIntoView(); }); }, beforeDestroy: function beforeDestroy() { /* istanbul ignore next */ if (this.sticky) { this.scrollHandler(false); } }, methods: { // whether to bind sticky listener scrollHandler: function scrollHandler(init) { this.scrollEl = this.scrollEl || _scroll2.default.getScrollEventTarget(this.$el); (init ? _event.on : _event.off)(this.scrollEl, 'scroll', this.onScroll, true); if (init) { this.onScroll(); } }, // adjust tab position onScroll: function onScroll() { var scrollTop = _scroll2.default.getScrollTop(this.scrollEl); var elTopToPageTop = _scroll2.default.getElementTop(this.$el); var elBottomToPageTop = elTopToPageTop + this.$el.offsetHeight - this.$refs.wrap.offsetHeight; if (scrollTop > elBottomToPageTop) { this.position = 'content-bottom'; } else if (scrollTop > elTopToPageTop) { this.position = 'page-top'; } else { this.position = 'content-top'; } }, // update nav bar style setNavBar: function setNavBar() { var _this2 = this; this.$nextTick(function () { if (!_this2.$refs.tabs) { return; } var tab = _this2.$refs.tabs[_this2.curActive]; _this2.navBarStyle = { width: (tab.offsetWidth || 0) + 'px', transform: 'translate(' + (tab.offsetLeft || 0) + 'px, 0)', transitionDuration: _this2.duration + 's' }; }); }, // correct the value of active correctActive: function correctActive(active) { active = +active; var exist = this.tabs.some(function (tab) { return tab.index === active; }); var defaultActive = (this.tabs[0] || {}).index || 0; this.curActive = exist ? active : defaultActive; }, // emit event when clicked onClick: function onClick(index) { if (this.tabs[index].disabled) { this.$emit('disabled', index); } else { this.$emit('click', index); this.curActive = index; } }, // scroll active tab into view scrollIntoView: function scrollIntoView() { if (!this.scrollable || !this.$refs.tabs) { return; } var tab = this.$refs.tabs[this.curActive]; var nav = this.$refs.nav; var scrollLeft = nav.scrollLeft, navWidth = nav.offsetWidth; var offsetLeft = tab.offsetLeft, tabWidth = tab.offsetWidth; this.scrollTo(nav, scrollLeft, offsetLeft - (navWidth - tabWidth) / 2); }, // animate the scrollLeft of nav scrollTo: function scrollTo(el, from, to) { var count = 0; var frames = Math.round(this.duration * 1000 / 16); var animate = function animate() { el.scrollLeft += (to - from) / frames; /* istanbul ignore next */ if (++count < frames) { (0, _raf.raf)(animate); } }; animate(); } } });