u-back-top.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <view @tap="backToTop" class="u-back-top" :class="['u-back-top--mode--' + mode]" :style="[{
  3. bottom: bottom + 'rpx',
  4. right: right + 'rpx',
  5. borderRadius: mode == 'circle' ? '10000rpx' : '8rpx',
  6. zIndex: uZIndex,
  7. opacity: opacity
  8. }, customStyle]">
  9. <view class="u-back-top__content" v-if="!$slots.default && !$slots.$default">
  10. <u-icon @click="backToTop" :name="icon" :custom-style="iconStyle"></u-icon>
  11. <view class="u-back-top__content__tips">
  12. {{tips}}
  13. </view>
  14. </view>
  15. <slot v-else />
  16. </view>
  17. </template>
  18. <script>
  19. export default {
  20. name: 'u-back-top',
  21. props: {
  22. // 返回顶部的形状,circle-圆形,square-方形
  23. mode: {
  24. type: String,
  25. default: 'circle'
  26. },
  27. // 自定义图标
  28. icon: {
  29. type: String,
  30. default: 'arrow-upward'
  31. },
  32. // 提示文字
  33. tips: {
  34. type: String,
  35. default: ''
  36. },
  37. // 返回顶部滚动时间
  38. duration: {
  39. type: [Number, String],
  40. default: 100
  41. },
  42. // 滚动距离
  43. scrollTop: {
  44. type: [Number, String],
  45. default: 0
  46. },
  47. // 距离顶部多少距离显示,单位rpx
  48. top: {
  49. type: [Number, String],
  50. default: 400
  51. },
  52. // 返回顶部按钮到底部的距离,单位rpx
  53. bottom: {
  54. type: [Number, String],
  55. default: 200
  56. },
  57. // 返回顶部按钮到右边的距离,单位rpx
  58. right: {
  59. type: [Number, String],
  60. default: 40
  61. },
  62. // 层级
  63. zIndex: {
  64. type: [Number, String],
  65. default: '9'
  66. },
  67. // 图标的样式,对象形式
  68. iconStyle: {
  69. type: Object,
  70. default () {
  71. return {
  72. color: '#909399',
  73. fontSize: '38rpx'
  74. }
  75. }
  76. },
  77. // 整个组件的样式
  78. customStyle: {
  79. type: Object,
  80. default () {
  81. return {}
  82. }
  83. }
  84. },
  85. watch: {
  86. showBackTop(nVal, oVal) {
  87. // 当组件的显示与隐藏状态发生跳变时,修改组件的层级和不透明度
  88. // 让组件有显示和消失的动画效果,如果用v-if控制组件状态,将无设置动画效果
  89. if (nVal) {
  90. this.uZIndex = this.zIndex;
  91. this.opacity = 1;
  92. } else {
  93. this.uZIndex = -1;
  94. this.opacity = 0;
  95. }
  96. }
  97. },
  98. computed: {
  99. showBackTop() {
  100. // 由于scrollTop为页面的滚动距离,默认为px单位,这里将用于传入的top(rpx)值
  101. // 转为px用于比较,如果滚动条到顶的距离大于设定的距离,就显示返回顶部的按钮
  102. // #ifndef APP-HARMONY
  103. return this.scrollTop > uni.upx2px(this.top);
  104. // #endif
  105. // #ifdef APP-HARMONY
  106. return this.scrollTop > this.top / 2;
  107. // #endif
  108. },
  109. },
  110. data() {
  111. return {
  112. // 不透明度,为了让组件有一个显示和隐藏的过渡动画
  113. opacity: 0,
  114. // 组件的z-index值,隐藏时设置为-1,就会看不到
  115. uZIndex: -1
  116. }
  117. },
  118. methods: {
  119. backToTop() {
  120. uni.pageScrollTo({
  121. scrollTop: 0,
  122. duration: this.duration
  123. });
  124. }
  125. }
  126. }
  127. </script>
  128. <style lang="scss" scoped>
  129. @import "../../libs/css/style.components.scss";
  130. .u-back-top {
  131. width: 80rpx;
  132. height: 80rpx;
  133. position: fixed;
  134. z-index: 9;
  135. @include vue-flex;
  136. flex-direction: column;
  137. justify-content: center;
  138. background-color: #E1E1E1;
  139. color: $u-content-color;
  140. align-items: center;
  141. transition: opacity 0.4s;
  142. &__content {
  143. @include vue-flex;
  144. flex-direction: column;
  145. align-items: center;
  146. &__tips {
  147. font-size: 24rpx;
  148. transform: scale(0.8);
  149. line-height: 1;
  150. }
  151. }
  152. }
  153. </style>