import manager from './popup-manager'; import context from './popup-context'; export default { props: { // popup 当前显示状态 value: { type: Boolean, default: false }, // 是否显示遮罩层 overlay: { type: Boolean, default: false }, // 点击遮罩层是否关闭 popup closeOnClickOverlay: { type: Boolean, default: false }, zIndex: [String, Number], // popup 滚动时是否禁用 body 滚动 lockOnScroll: { type: Boolean, default: true }, // 防止滚动穿透 preventScroll: { type: Boolean, default: false } }, watch: { value(val) { this[val ? 'open' : 'close'](); } }, beforeMount() { this._popupId = 'popup-' + context.plusKeyByOne('idSeed'); context.instances[this._popupId] = this; }, data() { return { opened: false, pos: { x: 0, y: 0 } }; }, methods: { recordPosition(e) { this.pos = { x: e.touches[0].clientX, y: e.touches[0].clientY }; }, watchTouchMove(e) { const pos = this.pos; const dx = e.touches[0].clientX - pos.x; const dy = e.touches[0].clientY - pos.y; const direction = dy > 0 ? '10' : '01'; const el = this.$el.querySelector('.scroller') || this.$el; const scrollTop = el.scrollTop; const scrollHeight = el.scrollHeight; const offsetHeight = el.offsetHeight; const isVertical = Math.abs(dx) < Math.abs(dy); let status = '11'; if (scrollTop === 0) { status = offsetHeight >= scrollHeight ? '00' : '01'; } else if (scrollTop + offsetHeight >= scrollHeight) { status = '10'; } if (status !== '11' && isVertical && !(parseInt(status, 2) & parseInt(direction, 2))) { e.preventDefault(); e.stopPropagation(); } }, open() { if (this.opened || this.$isServer) { return; } this.$emit('input', true); // 如果属性中传入了`zIndex`,则覆盖`context`中对应的`zIndex` if (this.zIndex !== undefined) { context.zIndex = this.zIndex; } if (this.overlay) { manager.openModal(this._popupId, context.plusKeyByOne('zIndex'), this.$el); if (this.lockOnScroll) { document.body.classList.add('van-overflow-hidden'); } } this.$el.style.zIndex = context.plusKeyByOne('zIndex'); this.opened = true; if (this.preventScroll) { document.addEventListener('touchstart', this.recordPosition, false); document.addEventListener('touchmove', this.watchTouchMove, false); } }, close() { if (!this.opened || this.$isServer) { return; } this.$emit('input', false); if (this.lockOnScroll) { document.body.classList.remove('van-overflow-hidden'); } this.opened = false; this.doAfterClose(); }, doAfterClose() { manager.closeModal(this._popupId); if (this.preventScroll) { document.removeEventListener('touchstart', this.recordPosition, false); document.removeEventListener('touchmove', this.watchTouchMove, false); } } }, beforeDestroy() { context.instances[this._popupId] = null; manager.closeModal(this._popupId); if (this.lockOnScroll) { document.body.classList.remove('van-overflow-hidden'); } } };