dict-tag.vue 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <template>
  2. <view class="dict-tag" :class="tagClass">{{ label }}</view>
  3. </template>
  4. <script setup>
  5. import { computed, getCurrentInstance, onMounted } from 'vue'
  6. import { useDict } from '@/utils/composables/useDict'
  7. const props = defineProps({
  8. // 字典类型
  9. dictType: {
  10. type: String,
  11. required: true
  12. },
  13. // 字典值
  14. value: {
  15. type: [String, Number],
  16. required: true
  17. },
  18. // 是否带颜色样式
  19. colored: {
  20. type: Boolean,
  21. default: true
  22. }
  23. })
  24. // 获取当前组件实例,用于访问父组件
  25. const instance = getCurrentInstance()
  26. // 初始化字典功能,但不自动加载
  27. const { dictData, loadDict, getDictLabel, getDictClass } = useDict([], { autoLoad: false })
  28. // 查找已加载指定字典类型的父组件
  29. const findParentWithDict = (dictType) => {
  30. let parent = instance.parent
  31. while (parent) {
  32. // 检查父组件是否有 dictData 并且包含指定类型的字典
  33. if (parent.ctx && parent.ctx.dictData && parent.ctx.dictData[dictType]) {
  34. console.log(`[DictTag] Found parent with dictionary ${dictType} already loaded`)
  35. return parent.ctx
  36. }
  37. parent = parent.parent
  38. }
  39. console.log(`[DictTag] No parent found with dictionary ${dictType}, loading it independently`)
  40. return null
  41. }
  42. // 计算属性:字典标签
  43. const label = computed(() => {
  44. return getDictLabel(props.dictType, props.value, '')
  45. })
  46. // 计算属性:标签样式类
  47. const tagClass = computed(() => {
  48. if (!props.colored) return ''
  49. const className = getDictClass(props.dictType, props.value, '')
  50. return className ? `tag-${className}` : ''
  51. })
  52. // 组件挂载时加载字典
  53. onMounted(() => {
  54. // 检查父组件是否已加载此字典
  55. const parentWithDict = findParentWithDict(props.dictType)
  56. if (parentWithDict) {
  57. // 父组件已加载此字典,使用父组件的字典数据
  58. if (parentWithDict.dictData && parentWithDict.dictData[props.dictType]) {
  59. dictData[props.dictType] = parentWithDict.dictData[props.dictType]
  60. }
  61. } else {
  62. // 父组件未加载此字典,自己加载
  63. loadDict([props.dictType])
  64. }
  65. })
  66. </script>
  67. <style scoped>
  68. .dict-tag {
  69. display: inline-block;
  70. padding: 0 10rpx;
  71. height: 40rpx;
  72. line-height: 40rpx;
  73. font-size: 26rpx;
  74. color: #666;
  75. border-radius: 20rpx;
  76. text-align: center;
  77. white-space: nowrap;
  78. }
  79. .tag-primary {
  80. color: #fff;
  81. background-color: #409EFF;
  82. }
  83. .tag-success {
  84. color: #fff;
  85. background-color: #67C23A;
  86. }
  87. .tag-info {
  88. color: #fff;
  89. background-color: #909399;
  90. }
  91. .tag-warning {
  92. color: #fff;
  93. background-color: #E6A23C;
  94. }
  95. .tag-danger {
  96. color: #fff;
  97. background-color: #F56C6C;
  98. }
  99. .tag-secondary {
  100. color: #fff;
  101. background-color: #8A69F9;
  102. }
  103. .tag-default {
  104. color: #333;
  105. background-color: #E9E9E9;
  106. }
  107. </style>