1.实列图片

image.png

2.代码部分

  1. <!--
  2. * @description:Clamp 文字显示
  3. * @author: wanghao
  4. * @Date: 2022-03-29 20:20:50
  5. * @Modified By:
  6. * @version: 1.0.0
  7. -->
  8. <template>
  9. <div ref="textOverflow" class="ami-clamp" :style="boxStyle">
  10. <div :class="autoresize === true ? 'autoresize':''">
  11. <!-- before 文字之前显示内容 -->
  12. <slot name="before"></slot>
  13. <ami-tooltip :disabled="showtip||expanded" :content="text" :placement="placement" :effect="effect">
  14. <span ref="overEllipsis">{{realText}}</span>
  15. </ami-tooltip>
  16. <!-- after 文字之后显示内容 -->
  17. <span class="slot-after" ref="slotRef" v-if="showSlotNode">
  18. <slot name="after"></slot>
  19. </span>
  20. </div>
  21. </div>
  22. </template>
  23. <script>
  24. export default {
  25. name: 'AmiClamp',
  26. props: {
  27. // 文本
  28. text: {
  29. type: String,
  30. default: ''
  31. },
  32. // 最大行数
  33. maxLines: {
  34. type: Number,
  35. default: 2
  36. },
  37. // 扩展(显示全部)
  38. expanded: {
  39. type: Boolean,
  40. default: false
  41. },
  42. // 省略符号
  43. ellipsis: {
  44. type: String,
  45. default: '...'
  46. },
  47. // 文字提示主题色
  48. effect: {
  49. type: String,
  50. default: 'dark'
  51. },
  52. // 文字显示对其方向 方向-对齐位置
  53. placement: {
  54. type: String,
  55. default: 'bottom'
  56. },
  57. // 是否显示(可见)
  58. showtip: {
  59. type: Boolean,
  60. default: false
  61. },
  62. // 宽度
  63. width: {
  64. type: Number,
  65. default: 0
  66. },
  67. // 最大高度
  68. maxHeight: {
  69. type: Number,
  70. default: 0
  71. },
  72. // 自动调整大小
  73. autoresize: {
  74. type: Boolean,
  75. default: false
  76. }
  77. },
  78. data() {
  79. return {
  80. offset: this.text.length,
  81. slotBoxWidth: 0,
  82. textBoxWidth: this.width,
  83. // 控制slot是否隐藏
  84. showSlotNode: false
  85. };
  86. },
  87. computed: {
  88. // 最大高度
  89. boxhight() {
  90. if (this.maxHeight) {
  91. return {
  92. height: this.maxHeight + 'px'
  93. };
  94. }
  95. },
  96. // 计算宽度
  97. boxStyle() {
  98. if (this.width) {
  99. return {
  100. width: this.width + 'px'
  101. };
  102. }
  103. },
  104. // 返回展示的文字
  105. realText() {
  106. // 是否被截取
  107. const isCutOut = this.offset !== this.text.length;
  108. let realText = this.text;
  109. if (isCutOut && !this.expanded) {
  110. // ellipsis 省略符号
  111. realText = this.text.slice(0, this.offset) + this.ellipsis;
  112. }
  113. return realText;
  114. }
  115. },
  116. watch: {
  117. realText(newVal, oldVal) {
  118. this.$emit('chang', newVal);
  119. }
  120. },
  121. methods: {
  122. // 计算截取位置
  123. calculateOffset(from, to) {
  124. this.$nextTick(() => {
  125. if (Math.abs(from - to) <= 1) return;
  126. if (this.isOverflow()) {
  127. to = this.offset;
  128. } else {
  129. from = this.offset;
  130. }
  131. this.offset = Math.floor((from + to) / 2);
  132. this.calculateOffset(from, to);
  133. });
  134. },
  135. // 判断是否超出最大行数
  136. isOverflow() {
  137. const { len, lastWidth } = this.getLines();
  138. if (len < this.maxLines) {
  139. return false;
  140. }
  141. if (this.maxLines) {
  142. // 超出部分 行数 > 最大行数 或则 已经是最大行数但最后一行宽度 + 后面内容超出正常宽度
  143. const lastLineOver = !!(len === this.maxLines && lastWidth + this.slotBoxWidth > this.textBoxWidth);
  144. if (len > this.maxLines || lastLineOver) {
  145. return true;
  146. }
  147. }
  148. return false;
  149. },
  150. // 获取当前文本行数
  151. getLines() {
  152. const clientRects = this.$refs.overEllipsis.getClientRects();
  153. return {
  154. len: clientRects.length,
  155. lastWidth: clientRects[clientRects.length - 1].width
  156. };
  157. }
  158. },
  159. mounted() {
  160. // 计算插槽内容宽度
  161. const { len } = this.getLines();
  162. if (len > this.maxLines) {
  163. this.showSlotNode = true;
  164. this.$nextTick(() => {
  165. this.slotBoxWidth = this.$refs.slotRef.clientWidth;
  166. this.textBoxWidth = this.$refs.textOverflow.clientWidth;
  167. this.calculateOffset(0, this.text.length);
  168. });
  169. }
  170. }
  171. };
  172. </script>

3.说明文档

Clamp 文字显示

多行文本展开收起

基础用法

image.png
在使用ami-clamp组件autoresize属性时必须指定宽高,否则会一直渲染,虽然做了防抖但是依旧会造成不必要的性能开销
width宽度

  1. <ami-clamp autoresize :showtip="false" :maxLines="maxLines" :width="400" :text="text"></ami-clamp>
  2. <script>
  3. export default {
  4. data(){
  5. return{
  6. text:"Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时",
  7. maxLines:2, //最大行数
  8. }
  9. }
  10. }
  11. </script>

最大行数

image.png
maxLines控制行数,最大的行数
maxLines控制行数,最大的行数

  1. <ami-clamp autoresize :showtip="false" :maxLines="maxLines" :width="400" :text="text"></ami-clamp>
  2. <script>
  3. export default {
  4. data() {
  5. return{
  6. text:"Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时",
  7. maxLines:3, //最大行数
  8. }
  9. },
  10. methods: {
  11. handleChange(value) {
  12. console.log(value);
  13. }
  14. }
  15. }
  16. </script>

插槽

image.png
expanded属性 控制文字展开(收起)
before文字前显示,after文字后显示

  1. <ami-clamp autoresize :maxLines="maxLines" :width="600" :text="text" :expanded="expanded">
  2. <ami-button slot="before" type="primary" size="mini" round>推荐</ami-button>
  3. <div slot="after">
  4. <ami-button type="text" @click="clickToggle()">{{expanded ? "收起" : "展开"}}</ami-button>
  5. </div>
  6. </ami-clamp>
  7. <script>
  8. export default {
  9. data() {
  10. return{
  11. text:"Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时",
  12. maxLines:3, //最大行数
  13. expanded:false
  14. }
  15. },
  16. methods: {
  17. clickToggle() {
  18. this.expanded = !this.expanded;
  19. }
  20. }
  21. }
  22. </script>

显示主题色

image.png
可以通过effect主题颜色,
在这里我们提供 9 种不同方向的展示方式,可以通过以下完整示例来理解,选择你要的效果。
effect主题颜色,dark默认,light 白色。placement属性值为:方向-对齐位置;四个方向:topleftrightbottom;三种对齐位置:start, end

  1. <ami-clamp :maxLines="maxLines" :expanded="expanded" :width="600" :text="text" placement="top" effect="light">
  2. <ami-button slot="before" type="primary" size="mini" round>推荐</ami-button>
  3. <div slot="after">
  4. <ami-button type="text" @click="clickToggle()">{{expanded ? "收起" : "展开"}}</ami-button>
  5. </div>
  6. </ami-clamp>
  7. <script>
  8. export default {
  9. data() {
  10. return{
  11. text:"Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合。另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时,Vue 也完全能够为复杂的单页应用提供驱动另一方面,当与现代化的工具链以及各种支持类库结合使用时",
  12. maxLines:3, //最大行数
  13. expanded:false,
  14. }
  15. },
  16. methods: {
  17. clickToggle() {
  18. this.expanded = !this.expanded;
  19. }
  20. }
  21. }
  22. </script>

Attributes

参数 说明 类型 可选值 默认值
text 文本 String
maxLines 最大行数 Number
expanded 扩展(显示全部) boolean true / false false
showtip 显示提示 boolean false
ellipsis 省略符号(可自己选择符号) String
effect 默认提示的主题 String dark / light dark
placement 文字显隐的出现位置 String top/top-start/top-end/bottom/bottom-start/bottom-end/left/left-start/left-end/right/right-start/right-end bottom
width 宽度 Number
autoresize 自动调整大小 boolean false

Clamp slot

name 说明
before 文字之前显示内容
after 文字之后显示内容