303 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
		
		
			
		
	
	
			303 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
| 
								 | 
							
								let bindIngXMixins = {}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// #ifdef APP-NVUE
							 | 
						||
| 
								 | 
							
								const BindingX = uni.requireNativePlugin('bindingx');
							 | 
						||
| 
								 | 
							
								const dom = uni.requireNativePlugin('dom');
							 | 
						||
| 
								 | 
							
								const animation = uni.requireNativePlugin('animation');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bindIngXMixins = {
							 | 
						||
| 
								 | 
							
									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() {
							 | 
						||
| 
								 | 
							
										this.swipeaction = this.getSwipeAction()
							 | 
						||
| 
								 | 
							
										if (this.swipeaction && Array.isArray(this.swipeaction.children)) {
							 | 
						||
| 
								 | 
							
											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) {
							 | 
						||
| 
								 | 
							
											// fix by mehaotian 禁止滑动
							 | 
						||
| 
								 | 
							
											if (this.disabled) return
							 | 
						||
| 
								 | 
							
											// 每次只触发一次,避免多次监听造成闪烁
							 | 
						||
| 
								 | 
							
											if (this.stop) return
							 | 
						||
| 
								 | 
							
											this.stop = true
							 | 
						||
| 
								 | 
							
											if (this.autoClose && this.swipeaction) {
							 | 
						||
| 
								 | 
							
												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()
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
												})
							 | 
						||
| 
								 | 
							
											})
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// #endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								export default bindIngXMixins
							 |