searchBar.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <script setup lang="ts">
  2. const props = withDefaults(
  3. defineProps<{
  4. height?: string | number
  5. searchInputValue?: string | number
  6. queryType?: string | number
  7. searchType?: string | number
  8. queryTypeData?: any[]
  9. searchPlaceholder?: string
  10. searchBtnText?: string
  11. searchBtnIcon?: string
  12. searchDropdownValue?: string[] | number[]
  13. searchDropdownList?: any[]
  14. searchTabList?: any[]
  15. }>(),
  16. {
  17. searchPlaceholder: "请输入搜索内容",
  18. searchDropdownList: () => [],
  19. searchDropdownValue: () => [],
  20. }
  21. )
  22. const emits = defineEmits<{
  23. (e: "update:searchInputValue", v: string | number): void
  24. (e: "update:queryType", v: string | number): void
  25. (e: "update:searchType", v: string | number): void
  26. (e: "update:searchDropdownValue", v: string[] | number[]): void
  27. (e: "changeQueryType", v: string | number): void
  28. (e: "search-btn"): void
  29. (e: "search"): void
  30. }>()
  31. const { searchInputValue, queryType, searchDropdownValue } = toRefs(props)
  32. const dropdownRef = ref<any[]>([])
  33. const style = computed(() => {
  34. const style: any = {}
  35. if (props.height) {
  36. style.height = addUnit(props.height)
  37. } else {
  38. style.height = props.queryTypeData?.length ? "130px" : "95px"
  39. }
  40. return style
  41. })
  42. const activeTabIndex = ref(0)
  43. const getDefaultSearchDropdownValue = () => {
  44. const arr = []
  45. for (let i = 0; i < props.searchDropdownList?.length; i++) {
  46. arr.push("")
  47. }
  48. return arr
  49. }
  50. function bindQueryChange(e: any) {
  51. activeTabIndex.value = 0
  52. emits("update:searchInputValue", "")
  53. emits("changeQueryType", e.detail.value)
  54. emits("update:queryType", e.detail.value)
  55. emits("update:searchType", "")
  56. emits("update:searchDropdownValue", getDefaultSearchDropdownValue())
  57. search()
  58. }
  59. function bindSearchBtnClick() {
  60. emits("search-btn")
  61. }
  62. function bindSearchTabClick(index: number, type?: string) {
  63. activeTabIndex.value = index
  64. if (index >= props.searchDropdownList.length) {
  65. dropdownRef.value.forEach((v: any) => {
  66. v.close()
  67. })
  68. emits("update:searchType", type || "")
  69. emits("update:searchDropdownValue", getDefaultSearchDropdownValue())
  70. search()
  71. } else {
  72. emits("update:searchType", "")
  73. }
  74. }
  75. function bindChangeDropdown(e: any, i: number) {
  76. searchDropdownValue.value[i] = e
  77. search()
  78. }
  79. function onSearch() {
  80. search()
  81. }
  82. function search() {
  83. nextTick(() => {
  84. emits("search")
  85. })
  86. }
  87. </script>
  88. <template>
  89. <view class="bg-white px-15 pt-15" :style="style">
  90. <view v-if="queryTypeData && queryTypeData.length" class="d-fc mb-10">
  91. <uni-data-checkbox
  92. v-model="queryType"
  93. :localdata="queryTypeData"
  94. selectedColor="var(--vb-color)"
  95. selectedTextColor="var(--vb-color)"
  96. @change="bindQueryChange"
  97. ></uni-data-checkbox>
  98. </view>
  99. <view class="d-flex align-center">
  100. <input
  101. class="w-100 px-20 h-40px br-30 me-15"
  102. type="text"
  103. :placeholder="searchPlaceholder"
  104. v-model="searchInputValue"
  105. style="background: #f2f2f2"
  106. confirm-type="search"
  107. adjust-position="false"
  108. auto-blur="true"
  109. @confirm="onSearch"
  110. />
  111. <vb-button
  112. v-if="searchBtnIcon || searchBtnText"
  113. custom-class="w-90px py-12 fs-15"
  114. round
  115. :icon="searchBtnIcon"
  116. icon-class="me-3"
  117. icon-size="20"
  118. size="small"
  119. @click="bindSearchBtnClick"
  120. >
  121. {{ searchBtnText }}
  122. </vb-button>
  123. </view>
  124. <view class="d-flex h-30px mt-10 pb-5 align-center">
  125. <template v-if="searchDropdownList?.length">
  126. <vb-dropdown
  127. v-for="(v, i) in searchDropdownList"
  128. ref="dropdownRef"
  129. v-model="searchDropdownValue[i]"
  130. :active="activeTabIndex == i"
  131. :empty-title="v.emptyTitle"
  132. :options="v.data"
  133. :key="i"
  134. :map="v.map"
  135. @click="bindSearchTabClick(i)"
  136. @change="(e:any) => bindChangeDropdown(e, i)"
  137. custom-class="px-8"
  138. ></vb-dropdown>
  139. </template>
  140. <template v-if="searchTabList && searchTabList.length > 0">
  141. <template v-for="(v, i) in searchTabList" :key="i">
  142. <view class="text-gray-4">|</view>
  143. <view
  144. class="px-5"
  145. :class="{ 'text-vb font-bold': activeTabIndex == i + (searchDropdownList?.length || 0) }"
  146. @click="bindSearchTabClick(i + (searchDropdownList?.length || 0), v.value)"
  147. >
  148. {{ v.text }}
  149. </view>
  150. </template>
  151. </template>
  152. </view>
  153. </view>
  154. </template>