TextEllipsis.vue 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. <script setup lang="ts">
  2. import { computed, ref } from 'vue';
  3. import type { TextProps } from '../basic/Text.vue';
  4. import Text from '../basic/Text.vue';
  5. import FlexCol from '../layout/FlexCol.vue';
  6. export interface TextEllipsisProps extends TextProps {
  7. lines?: number;
  8. expandable?: boolean;
  9. startOpen?: boolean;
  10. openText?: string;
  11. closeText?: string;
  12. }
  13. const emit = defineEmits(['expand', 'collapse']);
  14. const props = withDefaults(defineProps<TextEllipsisProps>(), {
  15. lines: 1,
  16. startOpen: false,
  17. expandable: false,
  18. openText: '展开',
  19. closeText: '收起',
  20. });
  21. const open = ref(props.startOpen);
  22. const currentLines = computed(() => {
  23. if (open.value)
  24. return undefined;
  25. return props.lines;
  26. });
  27. function handleClick() {
  28. open.value = !open.value;
  29. emit(open.value ? 'expand' : 'collapse');
  30. }
  31. defineOptions({
  32. options: {
  33. virtualHost: true,
  34. styleIsolation: "shared",
  35. },
  36. })
  37. </script>
  38. <template>
  39. <FlexCol>
  40. <Text
  41. :ellipsis="true"
  42. :lines="currentLines"
  43. v-bind="$attrs"
  44. >
  45. <slot>
  46. {{ text }}
  47. </slot>
  48. </Text>
  49. <slot v-if="expandable" name="button" :onClick="handleClick">
  50. <Text
  51. innerClass="nana-text-ellipsis-expand"
  52. touchable
  53. :text="open ? closeText : openText"
  54. color="primary"
  55. @click="handleClick"
  56. />
  57. </slot>
  58. </FlexCol>
  59. </template>
  60. <style>
  61. .nana-text-ellipsis-expand {
  62. /* #ifndef APP-NVUE */
  63. display: inline-block;
  64. /* #endif */
  65. text-align: right;
  66. }
  67. </style>