uni-swipe-action-item.vue 11 KB

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