Preview.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <template>
  2. <FlexCol :backgroundColor="backgroundColor">
  3. <!-- 标题区域 -->
  4. <slot name="title">
  5. <IconTextBlock
  6. :padding="padding"
  7. :title="title"
  8. :titleProps="titleProps"
  9. :desc="desc"
  10. :extra="extra"
  11. :extraProps="extraProps"
  12. />
  13. </slot>
  14. <Divider color="border.light" :size="2" />
  15. <!-- 项目区域 -->
  16. <slot name="items">
  17. <FlexCol :padding="padding">
  18. <PreviewItem
  19. v-for="(item,k) in items"
  20. :key="k"
  21. :title="item.title"
  22. :value="item.value"
  23. :titleProps="titleProps"
  24. :titleWidth="titleWidth"
  25. :titleColor="titleColor"
  26. :valueProps="valueProps"
  27. :valueColor="valueColor"
  28. :valueType="item.valueType"
  29. :gap="itemGap"
  30. :margin="itemVerticalPadding"
  31. />
  32. </FlexCol>
  33. </slot>
  34. <Divider color="border.light" :size="2" />
  35. <!-- 操作区域 -->
  36. <slot name="actions">
  37. <FlexRow align="stretch">
  38. <Button
  39. v-for="(item,k) in actions"
  40. :key="k"
  41. :text="item.text"
  42. :textColor="item.color"
  43. :innerStyle="{ flex: 1, minHeight: '60rpx' }"
  44. :radius="0"
  45. @click="item.onClick?.(item)"
  46. type="text"
  47. v-bind="item.props"
  48. />
  49. </FlexRow>
  50. </slot>
  51. </FlexCol>
  52. </template>
  53. <script setup lang="ts">
  54. import { computed } from 'vue';
  55. import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
  56. import FlexCol from '../layout/FlexCol.vue';
  57. import IconTextBlock from './block/IconTextBlock.vue';
  58. import PreviewItem, { type PreviewItemType } from './PreviewItem.vue';
  59. import type { TextProps } from '../basic/Text.vue';
  60. import Divider from './Divider.vue';
  61. import FlexRow from '../layout/FlexRow.vue';
  62. import type { ButtonProp } from '../basic/Button.vue';
  63. import Button from '../basic/Button.vue';
  64. const props = withDefaults(defineProps<{
  65. /**
  66. * 大标题
  67. */
  68. title?: string,
  69. /**
  70. * 副标题
  71. */
  72. desc?: string,
  73. /**
  74. * 大标题右侧额外信息
  75. */
  76. extra?: string,
  77. /**
  78. * 大标题右侧额外信息文字属性
  79. */
  80. extraProps?: TextProps,
  81. /**
  82. * 卡片背景颜色
  83. */
  84. backgroundColor?: string,
  85. /**
  86. * 项目列表
  87. */
  88. items?: {
  89. /**
  90. * 项目标题
  91. */
  92. title: string,
  93. /**
  94. * 项目值
  95. */
  96. value: string | string[],
  97. /**
  98. * 项目值类型
  99. * * text:普通文本
  100. * * image:图片
  101. */
  102. valueType?: PreviewItemType,
  103. }[],
  104. /**
  105. * 操作按钮列表
  106. */
  107. actions?: {
  108. /**
  109. * 操作按钮文字
  110. */
  111. text: string,
  112. /**
  113. * 操作按钮文字颜色
  114. */
  115. color?: string,
  116. /**
  117. * 操作按钮文字属性
  118. */
  119. props?: ButtonProp,
  120. /**
  121. * 操作按钮点击事件
  122. */
  123. onClick?: (item: { text: string, color?: string, props?: ButtonProp }) => void,
  124. }[],
  125. /**
  126. * 项目标题文字属性
  127. */
  128. titleProps?: TextProps,
  129. /**
  130. * 项目标题文字颜色
  131. * @default text.second
  132. */
  133. titleColor?: string,
  134. /**
  135. * 项目标题宽度
  136. * @default 300
  137. */
  138. titleWidth?: string|number,
  139. /**
  140. * 项目值文字颜色
  141. * @default text.content
  142. */
  143. valueColor?: string,
  144. /**
  145. * 项目值文字属性
  146. */
  147. valueProps?: TextProps,
  148. }>(), {
  149. backgroundColor: () => propGetThemeVar('PreviewBackgroundColor', 'white'),
  150. extraProps: () => propGetThemeVar('PreviewExtraTextProps', {}),
  151. titleColor: () => propGetThemeVar('PreviewTitleColor', 'text.second'),
  152. valueColor: () => propGetThemeVar('PreviewValueColor', 'text.content'),
  153. titleWidth: () => propGetThemeVar('PreviewItemTitleWidth', 300),
  154. titleProps: () => propGetThemeVar('PreviewItemTitleTextProps', {}),
  155. valueProps: () => propGetThemeVar('PreviewItemValueTextProps', {}),
  156. });
  157. const theme = useTheme();
  158. const padding = computed(() => theme.getVar('PreviewPadding', 30));
  159. const itemVerticalPadding = computed(() => theme.getVar('PreviewItemVerticalPadding', 10));
  160. const itemGap = computed(() => theme.getVar('PreviewItemGap', 20));
  161. </script>