fs-search.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <template>
  2. <view class="fs-search-box" :style="{backgroundColor: bgColor}">
  3. <view class="fs-search-box-left"><slot name="left"></slot></view>
  4. <view class="fs-input-box" :class="[{round}]" @click="handleLink" :style="{backgroundColor: inputBgColor}">
  5. <view class="sub fs-input" v-if="link">{{placeholder}}</view>
  6. <input
  7. v-else
  8. class="fs-input"
  9. :value="modelValue"
  10. :type="type"
  11. :placeholder="placeholder"
  12. @input="handleChange"
  13. @focus="handleFocus"
  14. @blur="handleBlur"
  15. :focus="autoFocus"
  16. />
  17. <view class="fs-icon fs-icon-search">
  18. <slot name="icon">
  19. <fs-icon type="icon-search" color="#666666" size="28rpx"></fs-icon>
  20. </slot>
  21. </view>
  22. <view class="fs-icon fs-icon-close" v-if="modelValue" @click="handleClear">
  23. <fs-icon type="icon-close-circle" color="#666666"></fs-icon>
  24. </view>
  25. </view>
  26. <view
  27. v-if="showAction"
  28. class="fs-cancel"
  29. :class="[actionColorType]"
  30. :style="{color:actionColor}"
  31. @click="handleAction"
  32. >
  33. {{actionText}}
  34. </view>
  35. <view class="fs-search-box-right"><slot name="right"></slot></view>
  36. </view>
  37. </template>
  38. <script setup>
  39. import { ref } from 'vue'
  40. const props = defineProps({
  41. placeholder: {
  42. type: String,
  43. default: '搜索'
  44. },
  45. actionColor: String,
  46. actionColorType: {
  47. type: String,
  48. validator(value) {
  49. return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
  50. }
  51. },
  52. actionText: {
  53. type: String,
  54. default: '取消'
  55. },
  56. autoFocus: Boolean,
  57. showAction: Boolean,
  58. round: Boolean,
  59. type: {
  60. type: String,
  61. default: 'text'
  62. },
  63. bgColor: {
  64. type: String,
  65. default: '#fff'
  66. },
  67. inputBgColor: {
  68. type: String,
  69. default: '#f0f0f0'
  70. },
  71. link: String,
  72. linkType: {
  73. type: String,
  74. default: 'navigateTo'
  75. },
  76. modelValue: String
  77. })
  78. const emits = defineEmits(['action', 'focus', 'blur', 'update:modelValue','change'])
  79. const handleChange = (e) => {
  80. emits('update:modelValue', e.detail.value)
  81. emits('change', e.detail.value)
  82. }
  83. const handleFocus = () => {
  84. emits('focus')
  85. }
  86. const handleBlur = () => {
  87. emits('blur')
  88. }
  89. const handleClear = () => {
  90. emits('update:modelValue', '')
  91. emits('change', '')
  92. }
  93. const handleAction = () => {
  94. emits('action', props.modelValue)
  95. }
  96. const handleLink = () => {
  97. if (props.link) {
  98. uni[props.linkType]({
  99. url: props.link
  100. })
  101. }
  102. }
  103. </script>
  104. <style lang="scss" scoped>
  105. .fs-search-box{
  106. width: 100%;
  107. height: 110rpx;
  108. padding: 20rpx var(--gutter);
  109. display: flex;
  110. background-color: #fff;
  111. box-sizing: border-box;
  112. align-items: center;
  113. }
  114. .fs-input-box {
  115. position: relative;
  116. height: 100%;
  117. width: 100%;
  118. flex: 1;
  119. background-color: #f0f0f0;
  120. .sub{
  121. line-height: 70rpx;
  122. color: var(--sub);
  123. }
  124. &.round{
  125. border-radius: 20px;
  126. .fs-input{
  127. border-radius: inherit;
  128. }
  129. }
  130. }
  131. .fs-input{
  132. height: 100%;
  133. width: 100%;
  134. padding-left: 68rpx;
  135. padding-right: 70rpx;
  136. border-radius: 6rpx;
  137. box-sizing: border-box;
  138. outline: none;
  139. /* #ifdef H5 */
  140. background-color: inherit;
  141. border: none;
  142. /* #endif */
  143. }
  144. .fs-cancel{
  145. margin-left: 20rpx;
  146. }
  147. .fs-icon{
  148. position: absolute;
  149. top: 50%;
  150. transform: translateY(-50%);
  151. color: var(--sub);
  152. z-index: 10;
  153. }
  154. .fs-icon-search{
  155. left: 20rpx;
  156. line-height: 1;
  157. }
  158. .fs-icon-close{
  159. right: 20rpx;
  160. }
  161. </style>