bab-Touchbox.vue 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. <template>
  2. <view>
  3. <view :class="isend?'fixedbox2' :'fixedbox'"
  4. :style="{'height':windowHeight + 'px','width':windowWidth + 'px','top':fixboxtop +'px','border-top-left-radius':radius,'border-top-right-radius':radius}"
  5. @touchmove="getstart($event)" @tap="tap" @touchend="getend" ref="fixbox">
  6. <view class="content" :style="{'height':windowHeight + 'px'}">
  7. <view class="tapBoxTouchLine" v-if="showLine">
  8. <view class="line"></view>
  9. </view>
  10. <slot />
  11. </view>
  12. </view>
  13. </view>
  14. </template>
  15. <script>
  16. /**
  17. * tapBox 触摸上拉组件
  18. * @description 触摸上拉组件,类似于高德美团上拉组件
  19. * @property {String} radius 左上右上圆角
  20. * @property {Number} minHeight 最低高度 占总屏幕高度占比
  21. * @property {Number} minHeight 最高高度 占总屏幕高度占比
  22. * @property {Number} touchHeight 允许滑动区域高度默认顶部横线高度 0为任意区域可滑动,单位rpx
  23. * @property {Boolean} showLine 上否显示顶部滑动线
  24. * @event {Function} tap 点击事件
  25. * @event {Function} getstart 开始滑动时触发事件
  26. * @event {Function} getend 滑动结束事件
  27. */
  28. export default {
  29. name: "tapBox",
  30. data() {
  31. return {
  32. windowHeight: 0, // 屏幕高度
  33. windowWidth: 0, // 屏幕宽度
  34. firsttop: 0, // 默认高度
  35. fixboxtop: 0, // 实际高度
  36. phonetop: 200, // 默认滑动分界线 - 后面计算为最低与最高的一半
  37. isend: false, // 触摸结束
  38. isfirst: true, // 手指第一次触摸
  39. tapboxtop: 0, // 手指距离顶部距离
  40. };
  41. },
  42. props: {
  43. radius: {
  44. type: String,
  45. default: '0'
  46. },
  47. minHeight: {
  48. type: Number,
  49. default: 0.2
  50. },
  51. maxHeight: {
  52. type: Number,
  53. default: 0.5
  54. },
  55. touchHeight: {
  56. type: Number,
  57. default: 0
  58. },
  59. showLine: {
  60. type: Boolean,
  61. default: true
  62. },
  63. },
  64. mounted() {
  65. this.$nextTick(function() {
  66. this.windowWidth = uni.getSystemInfoSync().windowWidth;
  67. this.windowHeight = uni.getSystemInfoSync().windowHeight;
  68. var defaultHeight = this.windowHeight * (1 - this.minHeight)
  69. this.firsttop = defaultHeight
  70. this.phonetop = (this.windowHeight * this.maxHeight - this.windowHeight * this.minHeight) /
  71. 2
  72. this.fixboxtop = defaultHeight
  73. this.$emit('currentHeight', (this.windowHeight - this.fixboxtop))
  74. this.$emit('maxtHeight', (this.windowHeight * this.maxHeight))
  75. })
  76. },
  77. onReady() {},
  78. computed: {},
  79. methods: {
  80. tap(e) {
  81. // console.log(e)
  82. },
  83. getstart(e) {
  84. var screenY;
  85. //#ifdef MP-WEIXIN
  86. screenY = e.touches[0].clientY;
  87. //#endif
  88. //#ifndef MP-WEIXIN
  89. screenY = e.touches[0].screenY;
  90. //#endif
  91. // console.log(screenY)
  92. // 这里特殊处理 解决:在滑动框内如果存在滚动元素,则会出现滑动时滑动框和内部滚动同时滑的问题
  93. // if (this.touchHeight !== 0) {
  94. // if (screenY - this.fixboxtop > this.touchHeight) {
  95. // return false;
  96. // }
  97. // }
  98. this.isend = false
  99. if (this.isfirst) {
  100. this.isfirst = false
  101. this.tapboxtop = screenY - this.fixboxtop
  102. }
  103. this.fixboxtop = screenY - this.tapboxtop
  104. if (this.fixboxtop > this.firsttop) { // 往下滑 不允许
  105. this.fixboxtop = this.firsttop
  106. } else {
  107. // 往上滑
  108. if (this.fixboxtop <= this.windowHeight * (1 - this.maxHeight)) {
  109. this.fixboxtop = this.windowHeight * (1 - this.maxHeight)
  110. }
  111. }
  112. this.$emit('currentHeight', (this.windowHeight - this.fixboxtop))
  113. },
  114. getend() {
  115. this.isend = true
  116. this.isfirst = true
  117. if ((this.firsttop - this.fixboxtop) <= this.phonetop) {
  118. this.fixboxtop = this.firsttop
  119. } else {
  120. this.fixboxtop = this.windowHeight * (1 - this.maxHeight)
  121. }
  122. this.$emit('currentHeight', (this.windowHeight - this.fixboxtop))
  123. }
  124. },
  125. }
  126. </script>
  127. <style lang="scss" scoped>
  128. .tapBoxTouchLine {
  129. margin-top: 20rpx;
  130. display: flex;
  131. align-items: center;
  132. justify-content: center;
  133. }
  134. .line {
  135. margin: 0px;
  136. vertical-align: middle;
  137. border-bottom: 8rpx solid rgb(214, 215, 217);
  138. width: 60rpx;
  139. transform: scaleY(0.5);
  140. border-top-color: rgb(214, 215, 217);
  141. border-right-color: rgb(214, 215, 217);
  142. border-left-color: rgb(214, 215, 217);
  143. }
  144. .fixedbox {
  145. position: fixed;
  146. left: 0;
  147. background-color: #FFFFFF;
  148. padding: 0 12px;
  149. box-sizing: border-box;
  150. }
  151. .fixedbox2 {
  152. position: fixed;
  153. left: 0;
  154. box-sizing: border-box;
  155. background-color: #FFFFFF;
  156. padding: 0 12px;
  157. transition-property: top;
  158. transition-duration: .8s;
  159. }
  160. </style>