const BindingX = uni.requireNativePlugin('bindingx'); const dom = uni.requireNativePlugin('dom'); const animation = uni.requireNativePlugin('animation'); export default { data() { return {} }, watch: { show(newVal) { if (this.autoClose) return if (this.stop) return this.stop = true if (newVal) { this.open(newVal) } else { this.close() } }, leftOptions() { this.getSelectorQuery() this.init() }, rightOptions(newVal) { this.init() } }, created() { if (this.swipeaction.children !== undefined) { this.swipeaction.children.push(this) } }, mounted() { this.box = this.getEl(this.$refs['selector-box--hock']) this.selector = this.getEl(this.$refs['selector-content--hock']); this.leftButton = this.getEl(this.$refs['selector-left-button--hock']); this.rightButton = this.getEl(this.$refs['selector-right-button--hock']); this.init() }, beforeDestroy() { this.swipeaction.children.forEach((item, index) => { if (item === this) { this.swipeaction.children.splice(index, 1) } }) }, methods: { init() { this.$nextTick(() => { this.x = 0 this.button = { show: false } setTimeout(() => { this.getSelectorQuery() }, 200) }) }, onClick(index, item, position) { this.$emit('click', { content: item, index, position }) }, touchstart(e) { // 每次只触发一次,避免多次监听造成闪烁 if (this.stop) return this.stop = true if (this.autoClose) { this.swipeaction.closeOther(this) } const leftWidth = this.button.left.width const rightWidth = this.button.right.width let expression = this.range(this.x, -rightWidth, leftWidth) let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0) let rightExpression = this.range(this.x + rightWidth, 0, rightWidth) this.eventpan = BindingX.bind({ anchor: this.box, eventType: 'pan', props: [{ element: this.selector, property: 'transform.translateX', expression }, { element: this.leftButton, property: 'transform.translateX', expression: leftExpression }, { element: this.rightButton, property: 'transform.translateX', expression: rightExpression }, ] }, (e) => { // nope if (e.state === 'end') { this.x = e.deltaX + this.x; this.isclick = true this.bindTiming(e.deltaX) } }); }, touchend(e) { if (this.isopen !== 'none' && !this.isclick) { this.open('none') } }, bindTiming(x) { const left = this.x const leftWidth = this.button.left.width const rightWidth = this.button.right.width const threshold = this.threshold if (!this.isopen || this.isopen === 'none') { if (left > threshold) { this.open('left') } else if (left < -threshold) { this.open('right') } else { this.open('none') } } else { if ((x > -leftWidth && x < 0) || x > rightWidth) { if ((x > -threshold && x < 0) || (x - rightWidth > threshold)) { this.open('left') } else { this.open('none') } } else { if ((x < threshold && x > 0) || (x + leftWidth < -threshold)) { this.open('right') } else { this.open('none') } } } }, /** * 移动范围 * @param {Object} num * @param {Object} mix * @param {Object} max */ range(num, mix, max) { return `min(max(x+${num}, ${mix}), ${max})` }, /** * 开启swipe */ open(type) { this.animation(type) }, /** * 关闭swipe */ close() { this.animation('none') }, /** * 开启关闭动画 * @param {Object} type */ animation(type) { const time = 300 const leftWidth = this.button.left.width const rightWidth = this.button.right.width if (this.eventpan && this.eventpan.token) { BindingX.unbind({ token: this.eventpan.token, eventType: 'pan' }) } switch (type) { case 'left': Promise.all([ this.move(this.selector, leftWidth), this.move(this.leftButton, 0), this.move(this.rightButton, rightWidth * 2) ]).then(() => { this.setEmit(leftWidth, type) }) break case 'right': Promise.all([ this.move(this.selector, -rightWidth), this.move(this.leftButton, -leftWidth * 2), this.move(this.rightButton, 0) ]).then(() => { this.setEmit(-rightWidth, type) }) break default: Promise.all([ this.move(this.selector, 0), this.move(this.leftButton, -leftWidth), this.move(this.rightButton, rightWidth) ]).then(() => { this.setEmit(0, type) }) } }, setEmit(x, type) { const leftWidth = this.button.left.width const rightWidth = this.button.right.width this.isopen = this.isopen || 'none' this.stop = false this.isclick = false // 只有状态不一致才会返回结果 if (this.isopen !== type && this.x !== x) { if (type === 'left' && leftWidth > 0) { this.$emit('change', 'left') } if (type === 'right' && rightWidth > 0) { this.$emit('change', 'right') } if (type === 'none') { this.$emit('change', 'none') } } this.x = x this.isopen = type }, move(ref, value) { return new Promise((resolve, reject) => { animation.transition(ref, { styles: { transform: `translateX(${value})`, }, duration: 150, //ms timingFunction: 'linear', needLayout: false, delay: 0 //ms }, function(res) { resolve(res) }) }) }, /** * 获取ref * @param {Object} el */ getEl(el) { return el.ref }, /** * 获取节点信息 */ getSelectorQuery() { Promise.all([ this.getDom('left'), this.getDom('right'), ]).then((data) => { let show = 'none' if (this.autoClose) { show = 'none' } else { show = this.show } if (show === 'none') { // this.close() } else { this.open(show) } }) }, getDom(str) { return new Promise((resolve, reject) => { dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], (data) => { if (data) { this.button[str] = data.size resolve(data) } else { reject() } }) }) } } }