searchBar.vue 4.7 KB

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