uni-swipe-action-item.vue 10 KB

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