fab.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <template>
  2. <!-- 全局公共悬浮按钮 -->
  3. <view @touchmove.stop.prevent>
  4. <view class="tui-fab-box" :class="{'tui-fab-right':!left || (left && right)}" :style="{left:getLeft(),right:getRight(),bottom:bottom+'rpx'}">
  5. <view class="tui-fab-btn" :class="{'tui-visible':isOpen,'tui-fab-hidden':hidden}">
  6. <div class="tui-fab-item-box" v-for="(item,index) in btnList" :key="index" @tap.stop="handleClick(index)">
  7. <div class="item-list">
  8. <div class="list-icon">
  9. <i class="iconfont" :class="[item.icon]"></i>
  10. </div>
  11. <div class="list-name">{{ item.name }}</div>
  12. </div>
  13. </div>
  14. </view>
  15. <view class="tui-fab-item" :class="{'tui-active':isOpen}" @tap.stop="handleClick(-1)">
  16. <i class="iconfont" :class="[isOpen? 'icontupiantianjia' : 'iconcaidan']"></i>
  17. </view>
  18. </view>
  19. <view class="tui-fab-mask" :class="{'tui-visible':isOpen}" @tap="handleClickCancel"></view>
  20. </view>
  21. </template>
  22. <script>
  23. // 拓展出来的按钮不应多于6个,否则违反了作为悬浮按钮的快速、高效的原则
  24. export default {
  25. name: 'tuiFab',
  26. props: {
  27. // rpx 为0时值为auto
  28. left: {
  29. type: Number,
  30. default: 0
  31. },
  32. // rpx 当为0时且left不为0,值为auto
  33. right: {
  34. type: Number,
  35. default: 20
  36. },
  37. // rpx bottom值
  38. bottom: {
  39. type: Number,
  40. default: 140
  41. },
  42. // 点击遮罩 是否可关闭
  43. maskClosable: {
  44. type: Boolean,
  45. default: true
  46. }
  47. },
  48. data() {
  49. return {
  50. isOpen: false,
  51. hidden: true,
  52. timer: null,
  53. btnList: [
  54. {
  55. name: '首页',
  56. icon: 'iconshouye',
  57. url: '/pages/admin/workbench'
  58. },
  59. {
  60. name: '添加图库',
  61. icon: 'icontianjiatuku',
  62. url: '/pages/admin/workbench'
  63. },
  64. {
  65. name: '发货',
  66. icon: 'iconfahuo',
  67. url: '/pages/admin/workbench'
  68. }
  69. ]
  70. }
  71. },
  72. methods: {
  73. getLeft() {
  74. let val = 'auto'
  75. if (this.left && !this.right) {
  76. val = this.left + 'rpx'
  77. }
  78. return val
  79. },
  80. getRight() {
  81. let val = this.right + 'rpx'
  82. if (this.left && !this.right) {
  83. val = 'auto'
  84. }
  85. return val
  86. },
  87. handleClick: function(index) {
  88. this.hidden = false
  89. clearTimeout(this.timer)
  90. if (index == -1 && this.btnList.length) {
  91. this.isOpen = !this.isOpen
  92. } else {
  93. this.$emit('click', {
  94. index: index
  95. })
  96. this.isOpen = false
  97. }
  98. if (!this.isOpen) {
  99. this.timer = setTimeout(() => {
  100. this.hidden = true
  101. }, 200)
  102. }
  103. },
  104. handleClickCancel: function() {
  105. if (!this.maskClosable) return
  106. this.isOpen = false
  107. }
  108. },
  109. beforeDestroy() {
  110. clearTimeout(this.timer)
  111. this.timer = null
  112. }
  113. }
  114. </script>
  115. <style lang="scss" scoped>
  116. .tui-fab-box {
  117. width: 100px;
  118. display: flex;
  119. justify-content: center;
  120. flex-direction: column;
  121. position: fixed;
  122. z-index: 99997;
  123. }
  124. .tui-fab-right {
  125. align-items: center;
  126. }
  127. .tui-fab-btn {
  128. transform: scale(0);
  129. transition: all 0.2s ease-in-out;
  130. opacity: 0;
  131. visibility: hidden;
  132. background-color: #fff;
  133. border-top-left-radius: 80px;
  134. border-top-right-radius: 80px;
  135. position: relative;
  136. top: 40px;
  137. padding: 30px 0 30px;
  138. }
  139. .tui-fab-hidden {
  140. height: 0;
  141. width: 0;
  142. }
  143. .tui-fab-item-box {
  144. display: flex;
  145. align-items: center;
  146. justify-content: center;
  147. padding-bottom: 30rpx;
  148. .item-list {
  149. text-align: center;
  150. color: #333;
  151. }
  152. .list-name {
  153. font-weight: 400;
  154. transform: scale(0.8);
  155. }
  156. }
  157. .tui-fab-item {
  158. display: flex;
  159. align-items: center;
  160. justify-content: center;
  161. box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.1);
  162. transition: all 0.2s linear;
  163. background-image: linear-gradient(0deg, #357eff, #0dc9fd);
  164. width: 100%;
  165. height: 100px;
  166. border-radius: 50%;
  167. color: #fff;
  168. }
  169. .tui-active {
  170. transform: rotate(135deg);
  171. }
  172. .tui-fab-mask {
  173. position: fixed;
  174. top: 0;
  175. left: 0;
  176. right: 0;
  177. bottom: 0;
  178. background: rgba(0, 0, 0, 0.75);
  179. z-index: 99996;
  180. transition: all 0.2s ease-in-out;
  181. opacity: 0;
  182. visibility: hidden;
  183. }
  184. .tui-visible {
  185. visibility: visible;
  186. opacity: 1;
  187. transform: scale(1);
  188. }
  189. </style>