uni-swipe-action-item.vue 11 KB

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