wd-tabbar-item.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <template>
  2. <view :class="`wd-tabbar-item ${customClass}`" :style="customStyle" @click="handleClick">
  3. <wd-badge v-bind="customBadgeProps">
  4. <view class="wd-tabbar-item__body">
  5. <slot name="icon" :active="active"></slot>
  6. <template v-if="!$slots.icon && icon">
  7. <wd-icon
  8. :name="icon"
  9. :custom-style="textStyle"
  10. :custom-class="`wd-tabbar-item__body-icon ${active ? 'is-active' : 'is-inactive'}`"
  11. ></wd-icon>
  12. </template>
  13. <text v-if="title" :style="textStyle" :class="`wd-tabbar-item__body-title ${active ? 'is-active' : 'is-inactive'}`">
  14. {{ title }}
  15. </text>
  16. </view>
  17. </wd-badge>
  18. </view>
  19. </template>
  20. <script lang="ts">
  21. export default {
  22. name: 'wd-tabbar-item',
  23. options: {
  24. addGlobalClass: true,
  25. virtualHost: true,
  26. styleIsolation: 'shared'
  27. }
  28. }
  29. </script>
  30. <script lang="ts" setup>
  31. import wdBadge from '../wd-badge/wd-badge.vue'
  32. import wdIcon from '../wd-icon/wd-icon.vue'
  33. import { type CSSProperties, computed } from 'vue'
  34. import { deepAssign, isDef, isUndefined, objToStyle, omitBy } from '../common/util'
  35. import { useParent } from '../composables/useParent'
  36. import { TABBAR_KEY } from '../wd-tabbar/types'
  37. import { tabbarItemProps } from './types'
  38. import type { BadgeProps } from '../wd-badge/types'
  39. const props = defineProps(tabbarItemProps)
  40. const { parent: tabbar, index } = useParent(TABBAR_KEY)
  41. const customBadgeProps = computed(() => {
  42. const badgeProps: Partial<BadgeProps> = deepAssign(
  43. isDef(props.badgeProps) ? omitBy(props.badgeProps, isUndefined) : {},
  44. omitBy(
  45. {
  46. max: props.max,
  47. isDot: props.isDot,
  48. modelValue: props.value
  49. },
  50. isUndefined
  51. )
  52. )
  53. if (!isDef(badgeProps.max)) {
  54. badgeProps.max = 99
  55. }
  56. return badgeProps
  57. })
  58. const textStyle = computed(() => {
  59. const style: CSSProperties = {}
  60. if (tabbar) {
  61. if (active.value && tabbar.props.activeColor) {
  62. style['color'] = tabbar.props.activeColor
  63. }
  64. if (!active.value && tabbar.props.inactiveColor) {
  65. style['color'] = tabbar.props.inactiveColor
  66. }
  67. }
  68. return `${objToStyle(style)}`
  69. })
  70. const active = computed(() => {
  71. const name = isDef(props.name) ? props.name : index.value
  72. if (tabbar) {
  73. if (tabbar.props.modelValue === name) {
  74. return true
  75. } else {
  76. return false
  77. }
  78. } else {
  79. return false
  80. }
  81. })
  82. /**
  83. * 点击tabbar选项
  84. */
  85. function handleClick() {
  86. const name: string | number = isDef(props.name) ? props.name : index.value
  87. tabbar && tabbar.setChange({ name })
  88. }
  89. </script>
  90. <style lang="scss" scoped>
  91. @import './index.scss';
  92. </style>