index.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. <template>
  2. <v-card class="card rightCardBox">
  3. <div v-if="showSelect" class="pa-3 currentSelect">
  4. <span>已选择:</span>
  5. <v-chip
  6. class="mr-3"
  7. label
  8. size="small"
  9. color="primary"
  10. closable
  11. v-for="k in currentSelect"
  12. :key="k.id"
  13. @click:close="handleClick(k)"
  14. >{{ k.name }}</v-chip>
  15. </div>
  16. <div class="rightCard" :style="{'width': isMobile ? '100%' : '786px', 'height': isMobile ? '300px' : '384px'}">
  17. <div v-for="item in items" :key="item.id">
  18. <div class="rowItem d-flex">
  19. <div class="categoryName2">{{ item.name }}</div>
  20. <div class="rightContent">
  21. <div v-if="!item.children?.length"></div>
  22. <div
  23. v-else
  24. :class="['jobItem', {'active': idChecked.includes(val.id)}]"
  25. v-for="val in item.children" :key="val.id"
  26. @click="handleClick(val)"
  27. >{{ val.name }}</div>
  28. </div>
  29. </div>
  30. </div>
  31. </div>
  32. </v-card>
  33. </template>
  34. <script setup>
  35. defineOptions({ name:'common-components-area'})
  36. import { getDict } from '@/hooks/web/useDictionaries'
  37. import { ref } from 'vue'
  38. import Snackbar from '@/plugins/snackbar'
  39. const emits = defineEmits(['handleClick'])
  40. const props = defineProps({
  41. limit: { // 限制最大可选择数量, 不限制传false或者0
  42. type: [Number, Boolean],
  43. default: 3
  44. },
  45. select: {
  46. type: Array,
  47. default: () => []
  48. },
  49. showSelect: {
  50. type: Boolean,
  51. default: false
  52. },
  53. currentData: {
  54. type: Array,
  55. default: () => []
  56. },
  57. isMobile: {
  58. type: Boolean,
  59. default: false
  60. }
  61. })
  62. let items = ref()
  63. let idChecked = ref([])
  64. let currentSelect = ref([])
  65. // 回显
  66. if (props.currentData.length) currentSelect.value = props.currentData
  67. if (props.select.length) idChecked.value = props.select.map(e => e + '') // 数据中的id是字符串
  68. getDict('areaTreeData', null, 'areaTreeData').then(({ data }) => {
  69. data = data?.length && data || []
  70. // const china = data.find(e => e.id === '1')
  71. // items.value = china?.children?.length ? china.children : []
  72. items.value = data
  73. })
  74. // 设置选中ids
  75. const handleClick = (val) => {
  76. const isExist = idChecked.value.includes(val.id)
  77. if (!isExist) {
  78. // 添加
  79. if (props.limit === 1) {
  80. currentSelect.value = [val]
  81. idChecked.value = [val.id]
  82. } else {
  83. if (props.limit === idChecked.value.length) return Snackbar.warning(`最多可选${props.limit}个城市`)
  84. currentSelect.value.push(val)
  85. idChecked.value.push(val.id)
  86. }
  87. } else {
  88. // 删除
  89. currentSelect.value = currentSelect.value.filter(e => e.id !== val.id)
  90. idChecked.value = idChecked.value.filter(e => e !== val.id)
  91. }
  92. emits('handleClick', idChecked.value, currentSelect.value)
  93. }
  94. </script>
  95. <style lang="scss" scoped>
  96. .currentSelect {
  97. position: sticky;
  98. background-color: var(--color-f2f4f7);
  99. }
  100. .card { border-radius: 12px; }
  101. .rightCard {
  102. position: relative;
  103. // height: 384px;
  104. // width: 786px;
  105. margin: 4px 0;
  106. padding: 0 16px;
  107. overflow-y: auto;
  108. .categoryName2 { font-size: 14px; color: #000; width: 150px; margin-right: 4px;}
  109. .jobItem { font-size: 14px; color: var(--color-333); }
  110. .active { color: var(--v-primary-base); font-weight: 700; }
  111. .rowItem {
  112. padding: 8px 0;
  113. }
  114. .divider {
  115. margin-left: 150px;
  116. }
  117. .rightContent {
  118. flex: 1;
  119. div {
  120. margin: 4px 28px 2px 0;
  121. float: left;
  122. cursor: pointer;
  123. &:hover {
  124. color: var(--v-primary-base);
  125. }
  126. }
  127. }
  128. }
  129. ::-webkit-scrollbar {
  130. width: 4px;
  131. height: 10px;
  132. }
  133. ::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
  134. // 滚动条-颜色
  135. background: #c3c3c379;
  136. }
  137. ::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
  138. // 滚动条-底色
  139. background: #e5e5e58f;
  140. }
  141. </style>