uv-back-top.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <uv-transition mode="fade" :customStyle="backTopStyle" :show="show">
  3. <slot>
  4. <view class="uv-back-top" :style="[contentStyle]" @click="backToTop">
  5. <uv-icon :name="icon" :custom-style="iconStyle"></uv-icon>
  6. <text v-if="text" class="uv-back-top__text">{{text}}</text>
  7. </view>
  8. </slot>
  9. </uv-transition>
  10. </template>
  11. <script>
  12. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
  13. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
  14. import props from './props.js';
  15. // #ifdef APP-NVUE
  16. const dom = weex.requireModule('dom')
  17. // #endif
  18. /**
  19. * backTop 返回顶部
  20. * @description 本组件一个用于长页面,滑动一定距离后,出现返回顶部按钮,方便快速返回顶部的场景。
  21. * @tutorial https://www.uvui.cn/components/backTop.html
  22. * @property {String} mode 返回顶部的形状,circle-圆形,square-方形 (默认 'circle' )
  23. * @property {String} icon 自定义图标 (默认 'arrow-upward' ) 见官方文档示例
  24. * @property {String} text 提示文字
  25. * @property {String | Number} duration 返回顶部滚动时间 (默认 100)
  26. * @property {String | Number} scrollTop 滚动距离 (默认 0 )
  27. * @property {String | Number} top 距离顶部多少距离显示,单位px (默认 400 )
  28. * @property {String | Number} bottom 返回顶部按钮到底部的距离,单位px (默认 100 )
  29. * @property {String | Number} right 返回顶部按钮到右边的距离,单位px (默认 20 )
  30. * @property {String | Number} zIndex 层级 (默认 9 )
  31. * @property {Object<Object>} iconStyle 图标的样式,对象形式 (默认 {color: '#909399',fontSize: '19px'})
  32. * @property {Object} customStyle 定义需要用到的外部样式
  33. *
  34. * @example <uv-back-top :scrollTop="scrollTop"></uv-back-top>
  35. */
  36. export default {
  37. name: 'uv-back-top',
  38. emits: ['click'],
  39. mixins: [mpMixin, mixin, props],
  40. computed: {
  41. backTopStyle() {
  42. // 动画组件样式
  43. const style = {
  44. bottom: this.$uv.addUnit(this.bottom),
  45. right: this.$uv.addUnit(this.right),
  46. width: '40px',
  47. height: '40px',
  48. position: 'fixed',
  49. zIndex: 10,
  50. }
  51. return style
  52. },
  53. show() {
  54. return this.$uv.getPx(this.scrollTop) > this.$uv.getPx(this.top)
  55. },
  56. contentStyle() {
  57. const style = {}
  58. let radius = 0
  59. // 是否圆形
  60. if (this.mode === 'circle') {
  61. radius = '100px'
  62. } else {
  63. radius = '4px'
  64. }
  65. // 为了兼容安卓nvue,只能这么分开写
  66. style.borderTopLeftRadius = radius
  67. style.borderTopRightRadius = radius
  68. style.borderBottomLeftRadius = radius
  69. style.borderBottomRightRadius = radius
  70. return this.$uv.deepMerge(style, this.$uv.addStyle(this.customStyle))
  71. }
  72. },
  73. methods: {
  74. backToTop() {
  75. // #ifdef APP-NVUE
  76. if (!this.$parent.$refs['uv-back-top']) {
  77. this.$uv.error(`nvue页面需要给页面最外层元素设置"ref='uv-back-top'`)
  78. }
  79. dom.scrollToElement(this.$parent.$refs['uv-back-top'], {
  80. offset: 0
  81. })
  82. // #endif
  83. // #ifndef APP-NVUE
  84. uni.pageScrollTo({
  85. scrollTop: 0,
  86. duration: this.duration
  87. });
  88. // #endif
  89. this.$emit('click')
  90. }
  91. }
  92. }
  93. </script>
  94. <style lang="scss" scoped>
  95. @import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
  96. $uv-back-top-flex: 1 !default;
  97. $uv-back-top-height: 100% !default;
  98. $uv-back-top-background-color: #E1E1E1 !default;
  99. $uv-back-top-tips-font-size: 12px !default;
  100. .uv-back-top {
  101. @include flex;
  102. flex-direction: column;
  103. align-items: center;
  104. flex: $uv-back-top-flex;
  105. height: $uv-back-top-height;
  106. justify-content: center;
  107. background-color: $uv-back-top-background-color;
  108. &__tips {
  109. font-size: $uv-back-top-tips-font-size;
  110. transform: scale(0.8);
  111. }
  112. }
  113. </style>