index.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. <template>
  2. <div class="d-flex align-center search" v-if="search.show">
  3. <ct-text-field
  4. v-model="searchValue"
  5. elevation="0"
  6. density="compact"
  7. hide-details
  8. variant="text"
  9. clear-icon="mdi-close-circle"
  10. append-inner-icon="mdi-magnify"
  11. placeholder="搜索职位/公司"
  12. class="search-fullHeight"
  13. type="text"
  14. clearable
  15. @click:append="sendMessage"
  16. @click:append-inner="toggleMarker"
  17. @click:clear="clearMessage"
  18. @click:prepend="changeIcon"
  19. >
  20. <template v-slot:append>
  21. <div class="full">
  22. <ct-btn class="search-fullHeight search-btn" block width="100" elevation="0" @click="handleSearch">搜索</ct-btn>
  23. </div>
  24. </template>
  25. <template v-slot:prepend v-if="list.key">
  26. <ct-menu :close-on-content-click="false">
  27. <template v-slot:activator="{ props }">
  28. <ct-btn
  29. class="full"
  30. color="primary"
  31. variant="text"
  32. v-bind="props"
  33. >
  34. {{ selectValue }}
  35. <ct-icon right>mdi-menu-down</ct-icon>
  36. </ct-btn>
  37. </template>
  38. <div class="list d-flex" @mouseleave="itemChildren = {}">
  39. <div class="list-left py-2">
  40. <div
  41. v-for="(item, index) in list.data"
  42. :key="'list' + index"
  43. class="list-left-item d-flex justify-space-between pa-2"
  44. :class="{ hover: itemChildren.value === item.value }"
  45. @mousemove="handleMousemove(item)"
  46. >
  47. {{ item.label }}
  48. <ct-icon v-if="item.children && item.children.length">mdi-menu-right</ct-icon>
  49. </div>
  50. </div>
  51. <div class="list-right pa-2 ml-1" v-show="itemChildren.children && itemChildren.children.length">
  52. <div class="text-h6">{{ itemChildren.label }}</div>
  53. <div v-for="item in itemChildren.children" :key="item.value" class="d-flex">
  54. <div class="list-right-title"></div>
  55. <div class="list-right-body"></div>
  56. </div>
  57. </div>
  58. </div>
  59. </ct-menu>
  60. </template>
  61. </ct-text-field>
  62. </div>
  63. <slot name="search-next"></slot>
  64. <div>
  65. <div v-for="item in option" :key="'search' + item.label" class="option">
  66. <div class="option-label">{{ item.label }}</div>
  67. <div class="option-value" @click="handleClick(item)">{{ item.items.find(e => e.value === item.value).label }}</div>
  68. </div>
  69. </div>
  70. </template>
  71. <script setup>
  72. import { ref, computed } from 'vue'
  73. defineOptions({ name: 'ct-search'})
  74. const props = defineProps({
  75. search: {
  76. type: Boolean,
  77. default: () => {
  78. return {
  79. show: true,
  80. placeholder: 'Search...'
  81. }
  82. }
  83. },
  84. list: {
  85. type: Object,
  86. default: () => {
  87. return {
  88. key: 'test',
  89. value: null,
  90. itemLabel: 'label',
  91. itemValue: 'value',
  92. data: []
  93. }
  94. }
  95. },
  96. option: {
  97. type: Array,
  98. default: () => []
  99. }
  100. })
  101. const itemChildren = ref({})
  102. const searchValue = ref(null)
  103. const selectValue = computed(() => {
  104. const label = props.list.itemLabel ?? 'label'
  105. const value = props.list.itemValue ?? 'value'
  106. const item = props.list.data.find(_e => _e.value === props.list[value])
  107. return item[label]
  108. })
  109. const handleMousemove = (item) => {
  110. const value = props.list.itemValue ?? 'value'
  111. if (itemChildren.value[value] === item.value) {
  112. return
  113. }
  114. itemChildren.value = item
  115. }
  116. const handleSearch = () => {
  117. }
  118. </script>
  119. <style lang="scss" scoped>
  120. .full {
  121. width: 100%;
  122. height: 100%;
  123. }
  124. .search {
  125. height: 50px;
  126. width: 800px;
  127. margin: 0 auto;
  128. border: 2px solid var(--v-primary-base);
  129. border-radius: 5px;
  130. overflow: hidden;
  131. &-fullHeight {
  132. height: 50px;
  133. }
  134. &-btn {
  135. font-size: 18px;
  136. color: #fff;
  137. background-color: var(--v-primary-base);
  138. }
  139. :deep(.v-field__input) {
  140. padding: 0;
  141. height: 100%;
  142. padding-left: 20px;
  143. }
  144. }
  145. .hover {
  146. color: var(--v-primary-base);
  147. background-color: var(--color-f8);
  148. }
  149. .list {
  150. height: 242px;
  151. &:hover {
  152. .list-right {
  153. display: block;
  154. }
  155. }
  156. &-left {
  157. background: #FFF;
  158. height: 100%;
  159. overflow-y: auto;
  160. }
  161. &-right {
  162. background: #FFF;
  163. display: none;
  164. width: 525px;
  165. height: 100%;
  166. overflow-y: auto;
  167. }
  168. }
  169. ::-webkit-scrollbar {
  170. width: 4px;
  171. height: 10px;
  172. }
  173. ::-webkit-scrollbar-thumb, .temporaryAdd ::-webkit-scrollbar-thumb, .details_edit ::-webkit-scrollbar-thumb {
  174. // 滚动条-颜色
  175. background: #c3c3c379;
  176. }
  177. ::-webkit-scrollbar-track, .temporaryAdd ::-webkit-scrollbar-track, .details_edit ::-webkit-scrollbar-track {
  178. // 滚动条-底色
  179. background: #e5e5e58f;
  180. }
  181. </style>