UNPKG

vivo-ui

Version:

vivo ui component lib for vue

224 lines (209 loc) 8.65 kB
(function () { if (typeof document !== 'undefined') { var head = document.head || document.getElementsByTagName('head')[0], style = document.createElement('style'), css = " .vui-swipeout { width: 100%; overflow: hidden; position: relative; } .vui-swipeout-button-grounp { position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: #eee; } .vui-swipeout-button-grounp > div { display: -webkit-flex; display: -webkit-box; display: -moz-box; display: -ms-flexbox; display: flex; -webkit-align-items: stretch; -webkit-box-align: stretch; -moz-box-align: stretch; -ms-flex-align: stretch; align-items: stretch; height: 100%; } .vui-swipeout-button-left > div { -webkit-box-pack: start; -moz-box-pack: start; -ms-flex-pack: start; justify-content: flex-start; -webkit-justify-content: flex-start; } .vui-swipeout-button-right > div { -webkit-box-pack: end; -moz-box-pack: end; -ms-flex-pack: end; justify-content: flex-end; -webkit-justify-content: flex-end; } .vui-swipeout-content { position: relative; background: #fff; } .vui-swipeout-content-animated { -webkit-transition: -webkit-transform 0.2s; transition: -webkit-transform 0.2s; -o-transition: -o-transform 0.2s; -moz-transition: transform 0.2s, -moz-transform 0.2s; transition: transform 0.2s; transition: transform 0.2s, -webkit-transform 0.2s, -moz-transform 0.2s, -o-transform 0.2s; transition: transform 0.2s, -webkit-transform 0.2s; } ";style.type = 'text/css';if (style.styleSheet) { style.styleSheet.cssText = css; } else { style.appendChild(document.createTextNode(css)); }head.appendChild(style); } })(); var swipeout = { render: function render() { var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('div', { class: _vm.prefixCls, on: { "touchstart": _vm.onPanStart, "mousedown": _vm.onPanStart, "touchmove": _vm.onPanMove, "mousemove": _vm.onPanMove, "touchend": _vm.onPanEnd, "mouseup": _vm.onPanEnd, "touchcancel": _vm.onPanEnd } }, [_c('div', { directives: [{ name: "show", rawName: "v-show", value: _vm.distX >= 0, expression: "distX >= 0" }], class: [_vm.prefixCls + '-button-grounp', _vm.prefixCls + '-button-left'] }, [_vm._t("left-button")], 2), _vm._v(" "), _c('div', { directives: [{ name: "show", rawName: "v-show", value: _vm.distX <= 0, expression: "distX <= 0" }], class: [_vm.prefixCls + '-button-grounp', _vm.prefixCls + '-button-right'] }, [_vm._t("right-button")], 2), _vm._v(" "), _c('div', { ref: "content", class: _vm.prefixCls + '-content', style: _vm.styles, on: { "mousedown": _vm.onContentClick, "touchstart": _vm.onContentClick } }, [_vm._t("default")], 2)]); }, staticRenderFns: [], name: 'swipeout', props: { disabled: Boolean, prefixCls: { type: String, default: 'vui-swipeout' }, threshold: { type: Number, default: 0.3 } }, data: function data() { return { pageX: undefined, // 记录start开始时到x位置 pageY: undefined, // 记录start开始时到y位置 distX: 0, // 拖动到x距离 distY: 0, // 拖动到x距离 styles: { transform: 'translate3d(0px, 0, 0)' }, opened: false, // swipe打开状态 initDirection: '', // 初始化swipe方向 leftWidth: 0, rightWidth: 0, needShowLeft: false, needShowRight: false, isScrolling: undefined // 判断滑动的轴(x || y) }; }, watch: { disabled: function disabled(newVal, oldVal) { if (newVal === true && !oldVal) { this.close(); } } }, computed: { buttonWidth: function buttonWidth() { if (this.leftWidth <= 0 && this.rightWidth > 0) { return this.rightWidth; } if (this.leftWidth > 0 && this.rightWidth <= 0) { return this.leftWidth; } if (this.leftWidth > 0 && this.rightWidth > 0) { return this.distX < 0 ? this.rightWidth : this.leftWidth; } } }, mounted: function mounted() { var _this = this; this.$nextTick(function () { if (_this.$slots['left-button']) { _this.needShowLeft = true; _this.caculateButtonWidth('left'); } if (_this.$slots['right-button']) { _this.needShowRight = true; _this.caculateButtonWidth('right'); } }); }, methods: { // 计算两侧按钮的总宽度 caculateButtonWidth: function caculateButtonWidth(direction) { var list = this.$slots[direction + '-button'][0].children.filter(function (node) { return node.tag; }); var width = 0; list.forEach(function (node) { return width += node.elm.clientWidth; }); this[direction + 'Width'] = width; }, // 点击内容区域关闭 onContentClick: function onContentClick() { if (this.styles.transform.indexOf('(0px, 0, 0)') === -1) this.close(); }, // 点击按钮 onButtonClick: function onButtonClick() { this.close(); }, onPanStart: function onPanStart(e) { if (this.disabled || this.opened) { return; } // 关闭已经打开的swipe var openedSwipe = this.$parent.$children.filter(function (item) { return item.$options._componentTag === 'swipeout' && item.$data.styles.transform.indexOf('(0px, 0, 0)') === -1; }); if (openedSwipe.length > 0) { openedSwipe.forEach(function (item) { item.close(); item._setStyle(true); }); e.preventDefault(); return; } var touch = e.touches ? e.touches[0] : e; this.pageX = touch.pageX; this.pageY = touch.pageY; }, onPanMove: function onPanMove(e) { if (this.disabled) { return; } if (this.pageX === undefined) { e.preventDefault(); return; } var touch = e.touches ? e.touches[0] : e; this.distX = touch.pageX - this.pageX; this.distY = touch.pageY - this.pageY; // 如果移动的x大于y说明是横向的,否则return if (typeof this.isScrolling === 'undefined') { this.isScrolling = !!(this.isScrolling || Math.abs(this.distY) > Math.abs(this.distX)); } if (this.isScrolling) { return; } // 设置初始方向值 if (!this.initDirection) { this.initDirection = this.distX > 0 ? 'toRight' : 'toLeft'; } if (this.distX > 0 && this.needShowLeft || this.distX < 0 && this.needShowRight) { this._setStyle(); if (Math.abs(this.distX) <= this.buttonWidth) { this._setOffset(this.distX); } else { var extra = (Math.abs(this.distX) - this.buttonWidth) * 0.5; var offset = (this.buttonWidth + extra) * (this.distX < 0 ? -1 : 1); this._setOffset(offset); } } e.preventDefault(); }, onPanEnd: function onPanEnd() { if (this.disabled || this.isScrolling) { return; } if (this.initDirection === 'toRight' && this.distX > 0) { if (this.distX > this.threshold * this.leftWidth) { this._setOffset(this.leftWidth); this.$emit('on-open'); this.opened = true; } else { this.close(); } } else if (this.initDirection === 'toLeft' && this.distX < 0) { if (Math.abs(this.distX) > this.threshold * this.rightWidth) { this._setOffset(-this.rightWidth); this.$emit('on-open'); this.opened = true; } else { this.close(); } } this._setStyle(true); this.pageX = this.pageY = undefined; this.initDirection = ''; this.isScrolling = undefined; }, open: function open(position) { this.distX = position === 'right' ? -this.rightWidth : this.leftWidth; this._setOffset(this.distX); this.opened = true; this._setStyle(true); }, close: function close() { var _this2 = this; this._setOffset(0); this.$emit('on-close'); setTimeout(function () { _this2.opened = false; }, 100); this.distX = 0; }, _setStyle: function _setStyle(animated) { if (animated) { this.$refs.content.classList.add('vui-swipeout-content-animated'); } else { this.$refs.content.classList.remove('vui-swipeout-content-animated'); } }, _setOffset: function _setOffset(x) { // 临界以后 if (this.initDirection === 'toRight' && x < 0 || this.initDirection === 'toLeft' && x > 0) { x = 0; } this.styles.transform = 'translate3d(' + x + 'px, 0, 0)'; } } }; export default swipeout;