image.png
    image.png
    需求就是超过四行得有个展开按钮,点击展开显示所有内容,不超过四行的话就不需要这个按钮并显示所有内容。且按钮在段落的后面

    • 首先得判断文本自否超过四行,因为这些一般都是是前端异步请求然后后端发送过来,使用了 Vue 中的 nextTick 来监听 DOM 中是数据变化。
    • 接下来主要是 css 上的思路,其实可以分为两部分,如下图,标号1的部分展示前面三行,标号为2的部分会根据1的行数判断缩进的大小,然后展示第四行。最后通过背景色的控制让两者看上去是一段文字。

    主要的点:
    第一部分:定位在文本框左上角,是三行高度直接截断
    第二部分:定位在文本框左上角,是4行高度写上省略号样式,右边空出五个字距离,然后整体缩进15个字,这样上面三行前面实际和第一部分重合,加上背景色与层级,会看的像一段文字

    1. {
    2. padding-right: 5em;
    3. text-intent: 15em;
    4. }

    第三部分:定位在右下角的展开全文的汉字,根据文本框里文本的真实高度是否大于4行来决定是否展示

    1. <template>
    2. <div
    3. class="text-box"
    4. :class="isCusp ? 'text-cusp-box' : ''"
    5. >
    6. <div
    7. class="text-desc"
    8. :class="isOpen ? 'total-desc' : ''"
    9. :title="title ? title+':'+content : content"
    10. >
    11. <div class="text-con" ref="desc">
    12. <span
    13. class="text-title"
    14. v-if="title"
    15. >{{title}}:</span>{{content}}
    16. </div>
    17. <div
    18. class="text-opt"
    19. v-if="isBtn"
    20. @click="change"
    21. >{{isOpen ? '收起全文' : '展开全文'}}</div>
    22. </div>
    23. </div>
    24. </template>
    25. <script>
    26. export default {
    27. props: {
    28. // 文字标题
    29. title: {
    30. type: String,
    31. default: ''
    32. },
    33. // 文字内容
    34. content: {
    35. type: String,
    36. default: ''
    37. },
    38. // 是否有尖头指向
    39. isCusp: {
    40. type: Boolean,
    41. default: false
    42. }
    43. },
    44. data() {
    45. return {
    46. // 内容信息
    47. info: '',
    48. // 是否展示按钮
    49. isBtn: false,
    50. // 按钮样子
    51. isOpen: true
    52. };
    53. },
    54. methods: {
    55. change() {
    56. this.isOpen = !this.isOpen;
    57. }
    58. },
    59. mounted() {
    60. this.info = this.content;
    61. },
    62. watch: {
    63. info(val) {
    64. let descHeight = window
    65. .getComputedStyle(this.$refs.desc)
    66. .height.replace('px', '');
    67. let rem = window.getComputedStyle(this.$refs.desc).lineHeight.replace('px', '');
    68. // 超过了四行
    69. if (descHeight > rem * 4) {
    70. // 显示展开收起按钮
    71. this.isBtn = true;
    72. this.isOpen = false;
    73. } else {
    74. // 不显示展开收起按钮
    75. this.isBtn = false;
    76. this.isOpen = true;
    77. }
    78. }
    79. }
    80. };
    81. </script>
    82. <style lang="less" scoped>
    83. .text-box {
    84. background: #f3f6f9;
    85. padding: 16px;
    86. border-radius: 8px;
    87. .text-desc {
    88. position: relative;
    89. max-height: 144px;
    90. line-height: 36px;
    91. word-wrap: break-word;
    92. word-break: break-all;
    93. overflow: hidden;
    94. .text-con {
    95. font-size: 24px;
    96. color: #77808a;
    97. line-height: 36px;
    98. .text-title {
    99. font-weight: bold;
    100. }
    101. }
    102. // 这是展开前实际显示的内容
    103. &:after,
    104. &:before {
    105. content: attr(title);
    106. position: absolute;
    107. left: 0;
    108. top: 0;
    109. width: 100%;
    110. font-size: 24px;
    111. color: #77808a;
    112. line-height: 36px;
    113. background: #f3f6f9;
    114. }
    115. // 把最后最后一行自身的上面三行遮住
    116. &:before {
    117. display: block;
    118. overflow: hidden;
    119. z-index: 1;
    120. max-height: 108px;
    121. }
    122. &:after {
    123. display: -webkit-box;
    124. -webkit-box-orient: vertical;
    125. overflow: hidden;
    126. height: 144px;
    127. -webkit-line-clamp: 4;
    128. text-overflow: ellipsis;
    129. -webkit-box-sizing: border-box;
    130. box-sizing: border-box;
    131. text-indent: -15em;
    132. padding-right: 5em;
    133. }
    134. &.total-desc{
    135. max-height: none;
    136. }
    137. &.total-desc:before{display: none;}
    138. &.total-desc:after{display: none;}
    139. }
    140. &.text-cusp-box {
    141. position: relative;
    142. margin-top: 30px;
    143. &:before {
    144. content: '';
    145. height: 0px;
    146. width: 0px;
    147. position: absolute;
    148. top: -14px;
    149. left: 105px;
    150. margin-left: -10px;
    151. z-index: 1;
    152. border-left: 14px solid transparent;
    153. border-right: 14px solid transparent;
    154. border-bottom: 24px solid #f3f6f9;
    155. }
    156. }
    157. .text-opt {
    158. position: absolute;
    159. font-size: 24px;
    160. color: #00c0eb;
    161. line-height: 36px;
    162. bottom: 0px;
    163. right: 0;
    164. z-index: 10;
    165. }
    166. }
    167. </style>