青蛙卖大米小程序2024-11-24
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.

162 lines
4.7 KiB

6 months ago
  1. <template>
  2. <view class="uv-read-more">
  3. <view
  4. class="uv-read-more__content"
  5. :style="{
  6. height: isLongContent && status === 'close' ? $uv.addUnit(showHeight) : $uv.addUnit(contentHeight,'px'),
  7. textIndent: textIndent
  8. }"
  9. >
  10. <view
  11. class="uv-read-more__content__inner"
  12. ref="uv-read-more__content__inner"
  13. :class="[elId]"
  14. >
  15. <slot></slot>
  16. </view>
  17. </view>
  18. <view
  19. class="uv-read-more__toggle"
  20. :style="[innerShadowStyle]"
  21. v-if="isLongContent"
  22. >
  23. <slot name="toggle">
  24. <view
  25. class="uv-read-more__toggle__text"
  26. @tap="toggleReadMore"
  27. >
  28. <uv-text
  29. :text="status === 'close' ? closeText : openText"
  30. :color="color"
  31. :size="fontSize"
  32. :lineHeight="fontSize"
  33. margin="0 5px 0 0"
  34. ></uv-text>
  35. <view class="uv-read-more__toggle__icon">
  36. <uv-icon
  37. :color="color"
  38. :size="fontSize + 2"
  39. :name="status === 'close' ? 'arrow-down' : 'arrow-up'"
  40. ></uv-icon>
  41. </view>
  42. </view>
  43. </slot>
  44. </view>
  45. </view>
  46. </template>
  47. <script>
  48. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js'
  49. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js'
  50. // #ifdef APP-NVUE
  51. const dom = uni.requireNativePlugin('dom')
  52. // #endif
  53. import props from './props.js';
  54. /**
  55. * readMore 阅读更多
  56. * @description 该组件一般用于内容较长预先收起一部分点击展开全部内容的场景
  57. * @tutorial https://www.uvui.cn/components/readMore.html
  58. * @property {String | Number} showHeight 内容超出此高度才会显示展开全文按钮单位px默认 400
  59. * @property {Boolean} toggle 展开后是否显示收起按钮默认 false
  60. * @property {String} closeText 关闭时的提示文字默认 '展开阅读全文'
  61. * @property {String} openText 展开时的提示文字默认 '收起'
  62. * @property {String} color 提示文字的颜色默认 '#2979ff'
  63. * @property {String | Number} fontSize 提示文字的大小单位px 默认 14
  64. * @property {Object} shadowStyle 显示阴影的样式
  65. * @property {String} textIndent 段落首行缩进的字符个数 默认 '2em'
  66. * @property {String | Number} name 用于在 open close 事件中当作回调参数返回
  67. * @event {Function} open 内容被展开时触发
  68. * @event {Function} close 内容被收起时触发
  69. * @example <uv-read-more><rich-text :nodes="content"></rich-text></uv-read-more>
  70. */
  71. export default {
  72. name: 'uv-read-more',
  73. mixins: [mpMixin, mixin, props],
  74. data() {
  75. return {
  76. isLongContent: false, // 是否需要隐藏一部分内容
  77. status: 'close', // 当前隐藏与显示的状态,close-收起状态,open-展开状态
  78. elId: '', // 生成唯一class
  79. contentHeight: 100, // 内容高度
  80. }
  81. },
  82. computed: {
  83. // 展开后无需阴影,收起时才需要阴影样式
  84. innerShadowStyle() {
  85. if (this.status === 'open') return {}
  86. else return this.shadowStyle
  87. }
  88. },
  89. created() {
  90. this.elId = this.$uv.guid();
  91. },
  92. mounted() {
  93. this.init()
  94. },
  95. methods: {
  96. async init() {
  97. this.getContentHeight().then(height => {
  98. this.contentHeight = height
  99. // 判断高度,如果真实内容高度大于占位高度,则显示收起与展开的控制按钮
  100. if (height > this.$uv.getPx(this.showHeight)) {
  101. this.isLongContent = true
  102. this.status = 'close'
  103. }
  104. })
  105. },
  106. // 获取内容的高度
  107. async getContentHeight() {
  108. // 延时一定时间再获取节点
  109. await this.$uv.sleep(30)
  110. return new Promise(resolve => {
  111. // #ifndef APP-NVUE
  112. this.$uvGetRect('.' + this.elId).then(res => {
  113. resolve(res.height)
  114. })
  115. // #endif
  116. // #ifdef APP-NVUE
  117. const ref = this.$refs['uv-read-more__content__inner']
  118. dom.getComponentRect(ref, (res) => {
  119. resolve(res.size.height)
  120. })
  121. // #endif
  122. })
  123. },
  124. // 展开或者收起
  125. toggleReadMore() {
  126. this.status = this.status === 'close' ? 'open' : 'close'
  127. // 如果toggle为false,隐藏"收起"部分的内容
  128. if (this.toggle == false) this.isLongContent = false
  129. // 发出打开或者收齐的事件
  130. this.$emit(this.status, this.name)
  131. }
  132. }
  133. }
  134. </script>
  135. <style lang="scss" scoped>
  136. @import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
  137. @import '@/uni_modules/uv-ui-tools/libs/css/color.scss';
  138. .uv-read-more {
  139. &__content {
  140. overflow: hidden;
  141. color: $uv-content-color;
  142. font-size: 15px;
  143. text-align: left;
  144. }
  145. &__toggle {
  146. @include flex;
  147. justify-content: center;
  148. &__text {
  149. @include flex;
  150. align-items: center;
  151. justify-content: center;
  152. margin-top: 5px;
  153. }
  154. }
  155. }
  156. </style>