You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
3.3 KiB

3 years ago
  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. return this.scrollTop > uni.upx2px(this.top);
  103. },
  104. },
  105. data() {
  106. return {
  107. // 不透明度,为了让组件有一个显示和隐藏的过渡动画
  108. opacity: 0,
  109. // 组件的z-index值,隐藏时设置为-1,就会看不到
  110. uZIndex: -1
  111. }
  112. },
  113. methods: {
  114. backToTop() {
  115. uni.pageScrollTo({
  116. scrollTop: 0,
  117. duration: this.duration
  118. });
  119. }
  120. }
  121. }
  122. </script>
  123. <style lang="scss" scoped>
  124. @import "../../libs/css/style.components.scss";
  125. .u-back-top {
  126. width: 80rpx;
  127. height: 80rpx;
  128. position: fixed;
  129. z-index: 9;
  130. @include vue-flex;
  131. flex-direction: column;
  132. justify-content: center;
  133. background-color: #E1E1E1;
  134. color: $u-content-color;
  135. align-items: center;
  136. transition: opacity 0.4s;
  137. &__content {
  138. @include vue-flex;
  139. flex-direction: column;
  140. align-items: center;
  141. &__tips {
  142. font-size: 24rpx;
  143. transform: scale(0.8);
  144. line-height: 1;
  145. }
  146. }
  147. }
  148. </style>