You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					348 lines
				
				10 KiB
			
		
		
			
		
	
	
					348 lines
				
				10 KiB
			| 
											3 years ago
										 | <template> | ||
|  | 	<!-- 在微信小程序 app vue端 h5 使用wxs 实现--> | ||
|  | 	<!-- #ifdef APP-VUE || MP-WEIXIN || H5 --> | ||
|  | 	<view class="uni-swipe"> | ||
|  | 		<!--  #ifdef MP-WEIXIN || VUE3 --> | ||
|  | 		<view class="uni-swipe_box" :change:prop="wxsswipe.showWatch" :prop="is_show" :data-threshold="threshold" | ||
|  | 			:data-disabled="disabled" @touchstart="wxsswipe.touchstart" @touchmove="wxsswipe.touchmove" | ||
|  | 			@touchend="wxsswipe.touchend"> | ||
|  | 			<!-- #endif --> | ||
|  | 			<!--  #ifndef MP-WEIXIN || VUE3 --> | ||
|  | 			<view class="uni-swipe_box" :change:prop="renderswipe.showWatch" :prop="is_show" :data-threshold="threshold" | ||
|  | 				:data-disabled="disabled+''" @touchstart="renderswipe.touchstart" @touchmove="renderswipe.touchmove" | ||
|  | 				@touchend="renderswipe.touchend"> | ||
|  | 				<!-- #endif --> | ||
|  | 				<!-- 在微信小程序 app vue端 h5 使用wxs 实现--> | ||
|  | 				<view class="uni-swipe_button-group button-group--left"> | ||
|  | 					<slot name="left"> | ||
|  | 						<view v-for="(item,index) in leftOptions" :key="index" :style="{ | ||
|  | 					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD' | ||
|  | 					}" class="uni-swipe_button button-hock" @touchstart="appTouchStart" | ||
|  | 							@touchend="appTouchEnd($event,index,item,'left')" | ||
|  | 							@click.stop="onClickForPC(index,item,'left')"> | ||
|  | 							<text class="uni-swipe_button-text" | ||
|  | 								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text> | ||
|  | 						</view> | ||
|  | 					</slot> | ||
|  | 				</view> | ||
|  | 				<view class="uni-swipe_text--center"> | ||
|  | 					<slot></slot> | ||
|  | 				</view> | ||
|  | 				<view class="uni-swipe_button-group button-group--right"> | ||
|  | 					<slot name="right"> | ||
|  | 						<view v-for="(item,index) in rightOptions" :key="index" :style="{ | ||
|  | 					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD' | ||
|  | 					}" class="uni-swipe_button button-hock" @touchstart="appTouchStart" | ||
|  | 							@touchend="appTouchEnd($event,index,item,'right')" | ||
|  | 							@click.stop="onClickForPC(index,item,'right')"><text class="uni-swipe_button-text" | ||
|  | 								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text> | ||
|  | 						</view> | ||
|  | 					</slot> | ||
|  | 				</view> | ||
|  | 			</view> | ||
|  | 		</view> | ||
|  | 		<!-- #endif --> | ||
|  | 		<!-- app nvue端 使用 bindingx --> | ||
|  | 		<!-- #ifdef APP-NVUE --> | ||
|  | 		<view ref="selector-box--hock" class="uni-swipe" @horizontalpan="touchstart" @touchend="touchend"> | ||
|  | 			<view ref='selector-left-button--hock' class="uni-swipe_button-group button-group--left"> | ||
|  | 				<slot name="left"> | ||
|  | 					<view v-for="(item,index) in leftOptions" :key="index" :style="{ | ||
|  | 				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD' | ||
|  | 				}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'left')"><text | ||
|  | 							class="uni-swipe_button-text" | ||
|  | 							:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF', fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text> | ||
|  | 					</view> | ||
|  | 				</slot> | ||
|  | 			</view> | ||
|  | 			<view ref='selector-right-button--hock' class="uni-swipe_button-group button-group--right"> | ||
|  | 				<slot name="right"> | ||
|  | 					<view v-for="(item,index) in rightOptions" :key="index" :style="{ | ||
|  | 				  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD' | ||
|  | 				}" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'right')"><text | ||
|  | 							class="uni-swipe_button-text" | ||
|  | 							:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'}">{{ item.text }}</text> | ||
|  | 					</view> | ||
|  | 				</slot> | ||
|  | 			</view> | ||
|  | 			<view ref='selector-content--hock' class="uni-swipe_box"> | ||
|  | 				<slot></slot> | ||
|  | 			</view> | ||
|  | 		</view> | ||
|  | 		<!-- #endif --> | ||
|  | 		<!-- 其他平台使用 js ,长列表性能可能会有影响--> | ||
|  | 		<!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ --> | ||
|  | 		<view class="uni-swipe"> | ||
|  | 			<view class="uni-swipe_box" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend" | ||
|  | 				:style="{transform:moveLeft}" :class="{ani:ani}"> | ||
|  | 				<view class="uni-swipe_button-group button-group--left" :class="[elClass]"> | ||
|  | 					<slot name="left"> | ||
|  | 						<view v-for="(item,index) in leftOptions" :key="index" :style="{ | ||
|  | 					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD', | ||
|  | 					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px' | ||
|  | 					}" class="uni-swipe_button button-hock" @touchstart="appTouchStart" | ||
|  | 							@touchend="appTouchEnd($event,index,item,'left')"><text class="uni-swipe_button-text" | ||
|  | 								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text> | ||
|  | 						</view> | ||
|  | 					</slot> | ||
|  | 				</view> | ||
|  | 				<slot></slot> | ||
|  | 				<view class="uni-swipe_button-group button-group--right" :class="[elClass]"> | ||
|  | 					<slot name="right"> | ||
|  | 						<view v-for="(item,index) in rightOptions" :key="index" :style="{ | ||
|  | 					  backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD', | ||
|  | 					  fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px' | ||
|  | 					}" @touchstart="appTouchStart" @touchend="appTouchEnd($event,index,item,'right')" | ||
|  | 							class="uni-swipe_button button-hock"><text class="uni-swipe_button-text" | ||
|  | 								:style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text> | ||
|  | 						</view> | ||
|  | 					</slot> | ||
|  | 				</view> | ||
|  | 			</view> | ||
|  | 		</view> | ||
|  | 		<!-- #endif --> | ||
|  | 
 | ||
|  | </template> | ||
|  | <script src="./wx.wxs" module="wxsswipe" lang="wxs"></script> | ||
|  | 
 | ||
|  | <script module="renderswipe" lang="renderjs"> | ||
|  | 	import render from './render.js' | ||
|  | 	export default { | ||
|  | 		mounted(e, ins, owner) { | ||
|  | 			this.state = {} | ||
|  | 		}, | ||
|  | 		methods: { | ||
|  | 			showWatch(newVal, oldVal, ownerInstance, instance) { | ||
|  | 				render.showWatch(newVal, oldVal, ownerInstance, instance, this) | ||
|  | 			}, | ||
|  | 			touchstart(e, ownerInstance) { | ||
|  | 				render.touchstart(e, ownerInstance, this) | ||
|  | 			}, | ||
|  | 			touchmove(e, ownerInstance) { | ||
|  | 				render.touchmove(e, ownerInstance, this) | ||
|  | 			}, | ||
|  | 			touchend(e, ownerInstance) { | ||
|  | 				render.touchend(e, ownerInstance, this) | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | </script> | ||
|  | <script> | ||
|  | 	import mpwxs from './mpwxs' | ||
|  | 	import bindingx from './bindingx.js' | ||
|  | 	import mpother from './mpother' | ||
|  | 
 | ||
|  | 	/** | ||
|  | 	 * SwipeActionItem 滑动操作子组件 | ||
|  | 	 * @description 通过滑动触发选项的容器 | ||
|  | 	 * @tutorial https://ext.dcloud.net.cn/plugin?id=181
 | ||
|  | 	 * @property {Boolean} show = [left|right|none] 	开启关闭组件,auto-close = false 时生效 | ||
|  | 	 * @property {Boolean} disabled = [true|false] 		是否禁止滑动 | ||
|  | 	 * @property {Boolean} autoClose = [true|false] 	滑动打开当前组件,是否关闭其他组件 | ||
|  | 	 * @property {Number}  threshold 					滑动缺省值 | ||
|  | 	 * @property {Array} leftOptions 					左侧选项内容及样式 | ||
|  | 	 * @property {Array} rgihtOptions 					右侧选项内容及样式 | ||
|  | 	 * @event {Function} click 							点击选项按钮时触发事件,e = {content,index} ,content(点击内容)、index(下标) | ||
|  | 	 * @event {Function} change 						组件打开或关闭时触发,left\right\none | ||
|  | 	 */ | ||
|  | 
 | ||
|  | 	export default { | ||
|  | 		mixins: [mpwxs, bindingx, mpother], | ||
|  | 		emits: ['click', 'change'], | ||
|  | 		props: { | ||
|  | 			// 控制开关
 | ||
|  | 			show: { | ||
|  | 				type: String, | ||
|  | 				default: 'none' | ||
|  | 			}, | ||
|  | 
 | ||
|  | 			// 禁用
 | ||
|  | 			disabled: { | ||
|  | 				type: Boolean, | ||
|  | 				default: false | ||
|  | 			}, | ||
|  | 
 | ||
|  | 			// 是否自动关闭
 | ||
|  | 			autoClose: { | ||
|  | 				type: Boolean, | ||
|  | 				default: true | ||
|  | 			}, | ||
|  | 
 | ||
|  | 			// 滑动缺省距离
 | ||
|  | 			threshold: { | ||
|  | 				type: Number, | ||
|  | 				default: 20 | ||
|  | 			}, | ||
|  | 
 | ||
|  | 			// 左侧按钮内容
 | ||
|  | 			leftOptions: { | ||
|  | 				type: Array, | ||
|  | 				default () { | ||
|  | 					return [] | ||
|  | 				} | ||
|  | 			}, | ||
|  | 
 | ||
|  | 			// 右侧按钮内容
 | ||
|  | 			rightOptions: { | ||
|  | 				type: Array, | ||
|  | 				default () { | ||
|  | 					return [] | ||
|  | 				} | ||
|  | 			} | ||
|  | 
 | ||
|  | 		}, | ||
|  | 		// #ifndef VUE3
 | ||
|  | 		// TODO vue2
 | ||
|  | 		destroyed() { | ||
|  | 			if (this.__isUnmounted) return | ||
|  | 			this.uninstall() | ||
|  | 		}, | ||
|  | 		// #endif
 | ||
|  | 		// #ifdef VUE3
 | ||
|  | 		// TODO vue3
 | ||
|  | 		unmounted() { | ||
|  | 			this.__isUnmounted = true | ||
|  | 			this.uninstall() | ||
|  | 		}, | ||
|  | 		// #endif
 | ||
|  | 
 | ||
|  | 		methods: { | ||
|  | 			uninstall() { | ||
|  | 				if (this.swipeaction) { | ||
|  | 					this.swipeaction.children.forEach((item, index) => { | ||
|  | 						if (item === this) { | ||
|  | 							this.swipeaction.children.splice(index, 1) | ||
|  | 						} | ||
|  | 					}) | ||
|  | 				} | ||
|  | 			}, | ||
|  | 			/** | ||
|  | 			 * 获取父元素实例 | ||
|  | 			 */ | ||
|  | 			getSwipeAction(name = 'uniSwipeAction') { | ||
|  | 				let parent = this.$parent; | ||
|  | 				let parentName = parent.$options.name; | ||
|  | 				while (parentName !== name) { | ||
|  | 					parent = parent.$parent; | ||
|  | 					if (!parent) return false; | ||
|  | 					parentName = parent.$options.name; | ||
|  | 				} | ||
|  | 				return parent; | ||
|  | 			} | ||
|  | 		} | ||
|  | 	} | ||
|  | </script> | ||
|  | <style lang="scss"> | ||
|  | 	.uni-swipe { | ||
|  | 		position: relative; | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		overflow: hidden; | ||
|  | 		/* #endif */ | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_box { | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		display: flex; | ||
|  | 		flex-shrink: 0; | ||
|  | 		// touch-action: none;
 | ||
|  | 		/* #endif */ | ||
|  | 		position: relative; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_content { | ||
|  | 		// border: 1px red solid;
 | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_text--center { | ||
|  | 		width: 100%; | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		cursor: grab; | ||
|  | 		/* #endif */ | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_button-group { | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		box-sizing: border-box; | ||
|  | 		display: flex; | ||
|  | 		/* #endif */ | ||
|  | 		flex-direction: row; | ||
|  | 		position: absolute; | ||
|  | 		top: 0; | ||
|  | 		bottom: 0; | ||
|  | 		/* #ifdef H5 */ | ||
|  | 		cursor: pointer; | ||
|  | 		/* #endif */ | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.button-group--left { | ||
|  | 		left: 0; | ||
|  | 		transform: translateX(-100%) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.button-group--right { | ||
|  | 		right: 0; | ||
|  | 		transform: translateX(100%) | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_button { | ||
|  | 		/* #ifdef APP-NVUE */ | ||
|  | 		flex: 1; | ||
|  | 		/* #endif */ | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		display: flex; | ||
|  | 		/* #endif */ | ||
|  | 		flex-direction: row; | ||
|  | 		justify-content: center; | ||
|  | 		align-items: center; | ||
|  | 		padding: 0 20px; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.uni-swipe_button-text { | ||
|  | 		/* #ifndef APP-NVUE */ | ||
|  | 		flex-shrink: 0; | ||
|  | 		/* #endif */ | ||
|  | 		font-size: 14px; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.ani { | ||
|  | 		transition-property: transform; | ||
|  | 		transition-duration: 0.3s; | ||
|  | 		transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/* #ifdef MP-ALIPAY */ | ||
|  | 	.movable-area { | ||
|  | 		/* width: 100%; */ | ||
|  | 		height: 45px; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.movable-view { | ||
|  | 		display: flex; | ||
|  | 		/* justify-content: center; */ | ||
|  | 		position: relative; | ||
|  | 		flex: 1; | ||
|  | 		height: 45px; | ||
|  | 		z-index: 2; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	.movable-view-button { | ||
|  | 		display: flex; | ||
|  | 		flex-shrink: 0; | ||
|  | 		flex-direction: row; | ||
|  | 		height: 100%; | ||
|  | 		background: #C0C0C0; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/* .transition { | ||
|  | 		transition: all 0.3s; | ||
|  | 	} */ | ||
|  | 
 | ||
|  | 	.movable-view-box { | ||
|  | 		flex-shrink: 0; | ||
|  | 		height: 100%; | ||
|  | 		background-color: #fff; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/* #endif */ | ||
|  | </style> |