| <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.stop="appTouchStart" | |
| 							@touchend.stop="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.stop="appTouchStart" | |
| 							@touchend.stop="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.stop="appTouchStart" | |
| 							@touchend.stop="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.stop="appTouchStart" @touchend.stop="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} rightOptions 					右侧选项内容及样式 | |
| 	 * @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>
 |