uni-swipe-action-item.vue 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. <template>
  2. <!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
  3. <!-- #ifdef APP-VUE || MP-WEIXIN || H5 -->
  4. <view class="uni-swipe">
  5. <view class="uni-swipe_box" :data-threshold="threshold" :data-disabled="disabled" :change:prop="swipe.sizeReady"
  6. :prop="btn" @touchstart="swipe.touchstart" @touchmove="swipe.touchmove" @touchend="swipe.touchend"
  7. @mousedown="swipe.mousedown" @mousemove="swipe.mousemove" @mouseup="swipe.mouseup"
  8. @mouseleave="swipe.mouseleave">
  9. <!-- 在微信小程序 app vue端 h5 使用wxs 实现-->
  10. <view class="uni-swipe_button-group button-group--left">
  11. <slot name="left">
  12. <view v-for="(item,index) in leftOptions" :data-button="btn" :key="index" :style="{
  13. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  14. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  15. }" class="uni-swipe_button button-hock" @touchstart="appTouchStart"
  16. @touchend="appTouchEnd($event,index,item,'left')" @click.stop="onClickForPC(index,item,'left')">
  17. <text class="uni-swipe_button-text"
  18. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  19. </view>
  20. </slot>
  21. </view>
  22. <view class="uni-swipe_text--center">
  23. <slot></slot>
  24. </view>
  25. <view class="uni-swipe_button-group button-group--right">
  26. <slot name="right">
  27. <view v-for="(item,index) in rightOptions" :data-button="btn" :key="index" :style="{
  28. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  29. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  30. }" class="uni-swipe_button button-hock" @touchstart="appTouchStart"
  31. @touchend="appTouchEnd($event,index,item,'right')"
  32. @click.stop="onClickForPC(index,item,'right')"><text class="uni-swipe_button-text"
  33. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  34. </view>
  35. </slot>
  36. </view>
  37. </view>
  38. </view>
  39. <!-- #endif -->
  40. <!-- app nvue端 使用 bindingx -->
  41. <!-- #ifdef APP-NVUE -->
  42. <view ref="selector-box--hock" class="uni-swipe" @horizontalpan="touchstart" @touchend="touchend">
  43. <view ref='selector-left-button--hock' class="uni-swipe_button-group button-group--left">
  44. <slot name="left">
  45. <view v-for="(item,index) in leftOptions" :data-button="btn" :key="index" :style="{
  46. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  47. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  48. }" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'left')"><text
  49. class="uni-swipe_button-text"
  50. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  51. </view>
  52. </slot>
  53. </view>
  54. <view ref='selector-right-button--hock' class="uni-swipe_button-group button-group--right">
  55. <slot name="right">
  56. <view v-for="(item,index) in rightOptions" :data-button="btn" :key="index" :style="{
  57. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  58. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  59. }" class="uni-swipe_button button-hock" @click.stop="onClick(index,item,'right')"><text
  60. class="uni-swipe_button-text"
  61. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  62. </view>
  63. </slot>
  64. </view>
  65. <view ref='selector-content--hock' class="uni-swipe_box">
  66. <slot></slot>
  67. </view>
  68. </view>
  69. <!-- #endif -->
  70. <!-- 其他平台使用 js ,长列表性能可能会有影响-->
  71. <!-- #ifdef MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ -->
  72. <view class="uni-swipe">
  73. <view class="uni-swipe_box" @touchstart="touchstart" @touchmove="touchmove" @touchend="touchend"
  74. :style="{transform:moveLeft}" :class="{ani:ani}">
  75. <view class="uni-swipe_button-group button-group--left">
  76. <slot name="left">
  77. <view v-for="(item,index) in leftOptions" :data-button="btn" :key="index" :style="{
  78. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  79. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  80. }" class="uni-swipe_button button-hock" @touchstart="appTouchStart"
  81. @touchend="appTouchEnd($event,index,item,'left')"><text class="uni-swipe_button-text"
  82. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  83. </view>
  84. </slot>
  85. </view>
  86. <slot></slot>
  87. <view class="uni-swipe_button-group button-group--right">
  88. <slot name="right">
  89. <view v-for="(item,index) in rightOptions" :data-button="btn" :key="index" :style="{
  90. backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD',
  91. fontSize: item.style && item.style.fontSize ? item.style.fontSize : '16px'
  92. }" @touchstart="appTouchStart" @touchend="appTouchEnd($event,index,item,'right')"
  93. class="uni-swipe_button button-hock"><text class="uni-swipe_button-text"
  94. :style="{color: item.style && item.style.color ? item.style.color : '#FFFFFF',}">{{ item.text }}</text>
  95. </view>
  96. </slot>
  97. </view>
  98. </view>
  99. </view>
  100. <!-- #endif -->
  101. </template>
  102. <script src="./index.wxs" module="swipe" lang="wxs"></script>
  103. <script>
  104. // #ifdef APP-VUE|| MP-WEIXIN || H5
  105. import mpwxs from './mpwxs'
  106. // #endif
  107. // #ifdef APP-NVUE
  108. import bindingx from './bindingx.js'
  109. // #endif
  110. // #ifndef APP-PLUS|| MP-WEIXIN || H5
  111. import mixins from './mpother'
  112. // #endif
  113. /**
  114. * SwipeActionItem 滑动操作子组件
  115. * @description 通过滑动触发选项的容器
  116. * @tutorial https://ext.dcloud.net.cn/plugin?id=181
  117. * @property {Boolean} show = [left|right|none] 开启关闭组件,auto-close = false 时生效
  118. * @property {Boolean} disabled = [true|false] 是否禁止滑动
  119. * @property {Boolean} autoClose = [true|false] 滑动打开当前组件,是否关闭其他组件
  120. * @property {Number} threshold 滑动缺省值
  121. * @property {Array} leftOptions 左侧选项内容及样式
  122. * @property {Array} rgihtOptions 右侧选项内容及样式
  123. * @event {Function} click 点击选项按钮时触发事件,e = {content,index} ,content(点击内容)、index(下标)
  124. * @event {Function} change 组件打开或关闭时触发,left\right\none
  125. */
  126. export default {
  127. // #ifdef APP-VUE|| MP-WEIXIN||H5
  128. mixins: [mpwxs],
  129. // #endif
  130. // #ifdef APP-NVUE
  131. mixins: [bindingx],
  132. // #endif
  133. // #ifndef APP-PLUS|| MP-WEIXIN || H5
  134. mixins: [mixins],
  135. // #endif
  136. props: {
  137. // 控制开关
  138. show: {
  139. type: String,
  140. default: 'none'
  141. },
  142. // 禁用
  143. disabled: {
  144. type: Boolean,
  145. default: false
  146. },
  147. // 是否自动关闭
  148. autoClose: {
  149. type: Boolean,
  150. default: true
  151. },
  152. // 滑动缺省距离
  153. threshold: {
  154. type: Number,
  155. default: 20
  156. },
  157. // 左侧按钮内容
  158. leftOptions: {
  159. type: Array,
  160. default () {
  161. return []
  162. }
  163. },
  164. // 右侧按钮内容
  165. rightOptions: {
  166. type: Array,
  167. default () {
  168. return []
  169. }
  170. }
  171. },
  172. // #ifndef VUE3
  173. // TODO vue2
  174. destroyed() {
  175. if (this.__isUnmounted) return
  176. this.uninstall()
  177. },
  178. // #endif
  179. // #ifdef VUE3
  180. // TODO vue3
  181. unmounted() {
  182. this.__isUnmounted = true
  183. this.uninstall()
  184. },
  185. // #endif
  186. methods: {
  187. uninstall() {
  188. if (this.swipeaction) {
  189. this.swipeaction.children.forEach((item, index) => {
  190. if (item === this) {
  191. this.swipeaction.children.splice(index, 1)
  192. }
  193. })
  194. }
  195. },
  196. /**
  197. * 获取父元素实例
  198. */
  199. getSwipeAction(name = 'uniSwipeAction') {
  200. let parent = this.$parent;
  201. let parentName = parent.$options.name;
  202. while (parentName !== name) {
  203. parent = parent.$parent;
  204. if (!parent) return false;
  205. parentName = parent.$options.name;
  206. }
  207. return parent;
  208. }
  209. }
  210. }
  211. </script>
  212. <style lang="scss" scoped>
  213. .uni-swipe {
  214. position: relative;
  215. /* #ifndef APP-NVUE */
  216. overflow: hidden;
  217. /* #endif */
  218. }
  219. .uni-swipe_box {
  220. /* #ifndef APP-NVUE */
  221. display: flex;
  222. flex-shrink: 0;
  223. // touch-action: none;
  224. /* #endif */
  225. position: relative;
  226. }
  227. .uni-swipe_content {
  228. // border: 1px red solid;
  229. }
  230. .uni-swipe_text--center {
  231. width: 100%;
  232. /* #ifndef APP-NVUE */
  233. cursor: grab;
  234. /* #endif */
  235. }
  236. .uni-swipe_button-group {
  237. /* #ifndef APP-NVUE */
  238. box-sizing: border-box;
  239. display: flex;
  240. /* #endif */
  241. flex-direction: row;
  242. position: absolute;
  243. top: 0;
  244. bottom: 0;
  245. /* #ifdef H5 */
  246. cursor: pointer;
  247. /* #endif */
  248. }
  249. .button-group--left {
  250. left: 0;
  251. transform: translateX(-100%)
  252. }
  253. .button-group--right {
  254. right: 0;
  255. transform: translateX(100%)
  256. }
  257. .uni-swipe_button {
  258. /* #ifdef APP-NVUE */
  259. flex: 1;
  260. /* #endif */
  261. /* #ifndef APP-NVUE */
  262. display: flex;
  263. /* #endif */
  264. flex-direction: row;
  265. justify-content: center;
  266. align-items: center;
  267. padding: 0 20px;
  268. }
  269. .uni-swipe_button-text {
  270. /* #ifndef APP-NVUE */
  271. flex-shrink: 0;
  272. /* #endif */
  273. font-size: 14px;
  274. }
  275. .ani {
  276. transition-property: transform;
  277. transition-duration: 0.3s;
  278. transition-timing-function: cubic-bezier(0.165, 0.84, 0.44, 1);
  279. }
  280. /* #ifdef MP-ALIPAY */
  281. .movable-area {
  282. /* width: 100%; */
  283. height: 45px;
  284. }
  285. .movable-view {
  286. display: flex;
  287. /* justify-content: center; */
  288. position: relative;
  289. flex: 1;
  290. height: 45px;
  291. z-index: 2;
  292. }
  293. .movable-view-button {
  294. display: flex;
  295. flex-shrink: 0;
  296. flex-direction: row;
  297. height: 100%;
  298. background: #C0C0C0;
  299. }
  300. /* .transition {
  301. transition: all 0.3s;
  302. } */
  303. .movable-view-box {
  304. flex-shrink: 0;
  305. height: 100%;
  306. background-color: #fff;
  307. }
  308. /* #endif */
  309. </style>