TextBlock.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. <script lang="ts">
  2. /**
  3. * 组件说明: 文本块。
  4. *
  5. * 可设置左右文字,左侧文字支持双行。
  6. *
  7. * 此组件适用于需要展示多行文本信息并具备一定交互性和布局灵活性的场景,如列表项、信息展示框等。
  8. */
  9. export default {}
  10. </script>
  11. <script setup lang="ts">
  12. import FlexCol from '../../layout/FlexCol.vue';
  13. import FlexRow from '../../layout/FlexRow.vue';
  14. import Text, { type TextProps } from '../../basic/Text.vue';
  15. import type { PropType } from 'vue';
  16. import Touchable from '@/components/feedback/Touchable.vue';
  17. defineEmits([ 'click' ])
  18. defineProps({
  19. /**
  20. * 主文本内容
  21. * @type {string}
  22. * @default ''
  23. */
  24. text : {
  25. type: String,
  26. default: '',
  27. },
  28. /**
  29. * 主文本的样式类名
  30. * @type {string}
  31. * @default 'contentLight'
  32. */
  33. textProps : {
  34. type: Object as PropType<TextProps>,
  35. default: () => ({
  36. color: 'text.second',
  37. fontSize: 26,
  38. }),
  39. },
  40. /**
  41. * 副文本内容
  42. * @type {string}
  43. * @default ''
  44. */
  45. text2 : {
  46. type: String,
  47. default: '',
  48. },
  49. /**
  50. * 副文本的样式类名
  51. * @type {string}
  52. * @default 'contentSecond'
  53. */
  54. text2Props : {
  55. type: Object as PropType<TextProps>,
  56. default: () => ({
  57. color: 'text.content',
  58. fontSize: 30,
  59. }),
  60. },
  61. /**
  62. * 前缀文本内容
  63. * @type {string}
  64. * @default ''
  65. */
  66. prefix : {
  67. type: String,
  68. default: '',
  69. },
  70. /**
  71. * 前缀文本样式类名
  72. * @type {string}
  73. * @default 'contentSecond'
  74. */
  75. prefixProps : {
  76. type: Object as PropType<TextProps>,
  77. default: () => ({
  78. color: 'text.content',
  79. }),
  80. },
  81. /**
  82. * 后缀文本内容
  83. * @type {string}
  84. * @default ''
  85. */
  86. suffix : {
  87. type: String,
  88. default: '',
  89. },
  90. /**
  91. * 后缀文本的样式类名
  92. * @type {string}
  93. * @default 'contentSecond'
  94. */
  95. suffixProps : {
  96. type: Object as PropType<TextProps>,
  97. default: () => ({
  98. color: 'text.content',
  99. }),
  100. },
  101. /**
  102. * 传递给根容器的额外属性对象
  103. * @type {Object}
  104. * @default undefined
  105. */
  106. viewProps: {
  107. type: Object,
  108. default: undefined
  109. },
  110. /**
  111. * 标识文本块是否可点击
  112. * @type {boolean}
  113. * @default false
  114. */
  115. touchable: {
  116. type: Boolean,
  117. default: false,
  118. },
  119. /**
  120. * 标识文本是否换行显示
  121. * @type {boolean}
  122. * @default false
  123. */
  124. wrap: {
  125. type: Boolean,
  126. default: false,
  127. },
  128. })
  129. </script>
  130. <template>
  131. <Touchable
  132. :touchable="touchable"
  133. justify="space-between"
  134. align="center"
  135. direction="row"
  136. v-bind="viewProps"
  137. @click="$emit('click')"
  138. >
  139. <slot name="prefix">
  140. <Text v-if="prefix" class="nana-text-prefix" v-bind="prefixProps" :text="prefix" />
  141. </slot>
  142. <slot>
  143. <FlexCol v-if="text2" class="nana-text">
  144. <Text
  145. :class="[
  146. 'nana-text',
  147. wrap ? 'wrap' : '',
  148. ]"
  149. v-bind="textProps"
  150. >
  151. {{ text }}
  152. </Text>
  153. <Text
  154. :class="[
  155. 'nana-text',
  156. wrap ? 'wrap' : '',
  157. ]"
  158. v-bind="text2Props"
  159. >
  160. {{ text2 }}
  161. </Text>
  162. </FlexCol>
  163. <Text
  164. v-else
  165. :class="[
  166. 'nana-text',
  167. wrap ? 'wrap' : '',
  168. ]"
  169. :v-bind="textProps"
  170. :text="text"
  171. />
  172. </slot>
  173. <slot name="suffix">
  174. <Text class="nana-text-suffix" v-bind="suffixProps" :text="suffix" />
  175. </slot>
  176. </Touchable>
  177. </template>
  178. <style lang="scss">
  179. .nana-text {
  180. white-space: nowrap;
  181. overflow: hidden;
  182. text-overflow: ellipsis;
  183. flex: 1 1 100%;
  184. max-width: 100%;
  185. &.wrap {
  186. white-space: normal;
  187. }
  188. }
  189. .nana-text-prefix {
  190. flex-shrink: 0;
  191. overflow: hidden;
  192. text-overflow: ellipsis;
  193. margin-right: 20rpx;
  194. }
  195. .nana-text-suffix {
  196. flex-shrink: 0;
  197. overflow: hidden;
  198. text-overflow: ellipsis;
  199. }
  200. </style>