wd-sidebar-item.vue 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <view
  3. @click="handleClick"
  4. :class="`wd-sidebar-item ${active ? 'wd-sidebar-item--active' : ''} ${prefix ? 'wd-sidebar-item--prefix' : ''} ${
  5. suffix ? 'wd-sidebar-item--suffix' : ''
  6. } ${disabled ? 'wd-sidebar-item--disabled' : ''} ${customClass}`"
  7. :style="customStyle"
  8. >
  9. <slot name="icon"></slot>
  10. <template v-if="!$slots.icon && icon">
  11. <wd-icon custom-class="wd-sidebar-item__icon" :name="icon"></wd-icon>
  12. </template>
  13. <wd-badge v-bind="customBadgeProps" custom-class="wd-sidebar-item__badge">
  14. {{ label }}
  15. </wd-badge>
  16. </view>
  17. </template>
  18. <script lang="ts">
  19. export default {
  20. name: 'wd-sidebar-item',
  21. options: {
  22. addGlobalClass: true,
  23. virtualHost: true,
  24. styleIsolation: 'shared'
  25. }
  26. }
  27. </script>
  28. <script lang="ts" setup>
  29. import wdIcon from '../wd-icon/wd-icon.vue'
  30. import wdBadge from '../wd-badge/wd-badge.vue'
  31. import { computed } from 'vue'
  32. import { useParent } from '../composables/useParent'
  33. import { SIDEBAR_KEY } from '../wd-sidebar/types'
  34. import { sidebarItemProps } from './types'
  35. import type { BadgeProps } from '../wd-badge/types'
  36. import { deepAssign, isDef, isUndefined, omitBy } from '../common/util'
  37. const props = defineProps(sidebarItemProps)
  38. const { parent: sidebar } = useParent(SIDEBAR_KEY)
  39. const customBadgeProps = computed(() => {
  40. const badgeProps: Partial<BadgeProps> = deepAssign(
  41. isDef(props.badgeProps) ? omitBy(props.badgeProps, isUndefined) : {},
  42. omitBy(
  43. {
  44. max: props.max,
  45. isDot: props.isDot,
  46. modelValue: props.badge
  47. },
  48. isUndefined
  49. )
  50. )
  51. if (!isDef(badgeProps.max)) {
  52. badgeProps.max = 99
  53. }
  54. return badgeProps
  55. })
  56. const active = computed(() => {
  57. let active: boolean = false
  58. if (sidebar && sidebar.props.modelValue === props.value) {
  59. active = true
  60. }
  61. return active
  62. })
  63. const prefix = computed(() => {
  64. let prefix: boolean = false
  65. if (sidebar) {
  66. let activeIndex: number = sidebar.children.findIndex((c: any) => {
  67. return c.value === sidebar.props.modelValue
  68. })
  69. let currentIndex: number = sidebar.children.findIndex((c: any) => {
  70. return c.value === props.value
  71. })
  72. if (currentIndex === activeIndex - 1) {
  73. prefix = true
  74. }
  75. }
  76. return prefix
  77. })
  78. const suffix = computed(() => {
  79. let suffix: boolean = false
  80. if (sidebar) {
  81. let activeIndex: number = sidebar.children.findIndex((c: any) => {
  82. return c.value === sidebar.props.modelValue
  83. })
  84. let currentIndex: number = sidebar.children.findIndex((c: any) => {
  85. return c.value === props.value
  86. })
  87. if (currentIndex === activeIndex + 1) {
  88. suffix = true
  89. }
  90. }
  91. return suffix
  92. })
  93. function handleClick() {
  94. if (props.disabled) {
  95. return
  96. }
  97. sidebar && sidebar.setChange(props.value, props.label)
  98. }
  99. </script>
  100. <style lang="scss" scoped>
  101. @import './index.scss';
  102. </style>