Divider.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <template>
  2. <view
  3. :class="[
  4. 'nana-divider',
  5. type,
  6. orientation,
  7. ]"
  8. :style="outStyle"
  9. >
  10. <template v-if="text">
  11. <view class="line left" :style="lineStyle">
  12. <view class="bar" :style="barStyle" />
  13. </view>
  14. <text class="line center" :style="{
  15. ...lineStyle,
  16. ...textStyle
  17. }">{{ text }}</text>
  18. <view class="line right">
  19. <view class="bar" :style="barStyle" />
  20. </view>
  21. </template>
  22. <view v-else class="line" :style="lineStyle">
  23. <view class="bar" :style="barStyle" />
  24. </view>
  25. </view>
  26. </template>
  27. <script setup lang="ts">
  28. import { computed } from 'vue';
  29. import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
  30. type DividerOrientationTypes = 'left' | 'right' | 'center';
  31. export interface DividerProps {
  32. /**
  33. * 是否虚线
  34. * @default false
  35. */
  36. dashed?: boolean;
  37. /**
  38. * 是否虚线 (dotted)
  39. * @default false
  40. */
  41. dotted?: boolean
  42. /**
  43. * 线的颜色,默认 gray
  44. * @default gray
  45. */
  46. color?: string;
  47. /**
  48. * 线的颜色
  49. * @default none
  50. */
  51. backgroundColor?: string;
  52. /**
  53. * 分割线标题的位置,默认 center
  54. */
  55. orientation?: DividerOrientationTypes;
  56. /**
  57. * 水平还是垂直类型
  58. * @default 'horizontal'
  59. */
  60. type?: 'horizontal' | 'vertical';
  61. /**
  62. * 分割线上面的文字(仅水平状态有效)
  63. */
  64. text?: string,
  65. /**
  66. * 分割线上面的文字样式
  67. */
  68. textStyle?: object,
  69. /**
  70. * 分割线宽度
  71. * @default 1
  72. */
  73. width?: number;
  74. /**
  75. * 容器大小(垂直的时候是宽度,水平的时候是高度)
  76. * @default 36
  77. */
  78. size?: number;
  79. }
  80. const theme = useTheme();
  81. const props = withDefaults(defineProps<DividerProps>(), {
  82. color: () => propGetThemeVar('DividerColor', 'grey'),
  83. backgroundColor: () => propGetThemeVar('DividerBackgroundColor', undefined)!,
  84. width: () => propGetThemeVar('DividerWidth', 2),
  85. size: () => propGetThemeVar('DividerSize', 36),
  86. type: 'horizontal',
  87. orientation: 'center',
  88. });
  89. const outStyle = computed(() => {
  90. return {
  91. backgroundColor: theme.resolveThemeColor(props.backgroundColor),
  92. }
  93. })
  94. const lineStyle = computed(() => {
  95. return {
  96. fontSize: '22rpx',
  97. color: theme.resolveThemeColor(props.color),
  98. width: theme.resolveThemeSize(props.type === 'horizontal' ? '100%' : props.size),
  99. height: theme.resolveThemeSize(props.type === 'vertical' ? '100%' : props.size),
  100. }
  101. })
  102. const barStyle = computed(() => {
  103. const border = `${theme.resolveThemeSize(props.width)} ${props.dashed ? 'dashed' : 'solid'} ${theme.resolveThemeColor(props.color)}`
  104. return {
  105. borderLeft: props.type === 'vertical' ? border : undefined,
  106. borderTop: props.type === 'vertical' ? undefined : border,
  107. width: theme.resolveThemeSize(props.type === 'horizontal' ? '100%' : props.width),
  108. height: theme.resolveThemeSize(props.type === 'vertical' ? '100%' : props.width),
  109. }
  110. })
  111. </script>
  112. <style lang="scss">
  113. .nana-divider {
  114. position: relative;
  115. display: flex;
  116. justify-content: center;
  117. align-items: center;
  118. align-self: stretch;
  119. .line {
  120. position: relative;
  121. display: flex;
  122. justify-content: center;
  123. align-items: center;
  124. flex: 1;
  125. &.center {
  126. flex-shrink: 0;
  127. text-align: center;
  128. }
  129. }
  130. &.left {
  131. .line.left {
  132. flex: 0.25;
  133. }
  134. }
  135. &.right {
  136. .line.right {
  137. flex: 0.25;
  138. }
  139. }
  140. &.vertical {
  141. flex-direction: column;
  142. height: 100%;
  143. }
  144. &.horizontal {
  145. flex-direction: row;
  146. }
  147. }
  148. </style>