fs-search.vue 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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"><fs-icon type="icon-search" color="#666666" size="28rpx"></fs-icon></slot>
  19. </view>
  20. <view class="fs-icon fs-icon-close" v-if="modelValue" @click="handleClear">
  21. <fs-icon type="icon-close-circle" color="#666666"></fs-icon>
  22. </view>
  23. </view>
  24. <view
  25. v-if="showAction"
  26. class="fs-cancel"
  27. :class="[actionColorType]"
  28. :style="{ color: actionColor }"
  29. @click="handleAction"
  30. >
  31. {{ actionText }}
  32. </view>
  33. <view class="fs-search-box-right"><slot name="right"></slot></view>
  34. </view>
  35. </template>
  36. <script>
  37. /**
  38. * 搜索组件
  39. * @description 搜索组件
  40. * @property {String} placeholder 占位符
  41. * @property {String} type 输入框类型
  42. * @property {String} actionColor 操作文字颜色
  43. * @property {String} actionColorType = [primary | danger | warning | info | success] 操作文字颜色类型
  44. * @property {String} actionText 操作文字
  45. * @property {String} bgColor 背景颜色
  46. * @property {String} inputBgColor 输入框背景颜色
  47. * @property {String} showAction 是否显示操作
  48. * @property {String} round 是否圆角
  49. * @property {String} autoFocus 是否圆角
  50. * @property {String} link 跳转地址
  51. * @property {String} linkType 跳转类型
  52. * @event {Function} focus 输入框聚焦事件
  53. * @event {Function} blur 输入框失去焦点事件
  54. * @event {Function} change 输入框内容变化事件
  55. * @event {Function} action 点击操作事件
  56. */
  57. export default {
  58. name: 'fs-search'
  59. }
  60. </script>
  61. <script setup>
  62. import { ref } from 'vue'
  63. const props = defineProps({
  64. placeholder: {
  65. type: String,
  66. default: '搜索'
  67. },
  68. actionColor: String,
  69. actionColorType: {
  70. type: String,
  71. validator(value) {
  72. return ['primary', 'success', 'info', 'warning', 'danger'].includes(value)
  73. }
  74. },
  75. actionText: {
  76. type: String,
  77. default: '取消'
  78. },
  79. autoFocus: Boolean,
  80. showAction: Boolean,
  81. round: Boolean,
  82. type: {
  83. type: String,
  84. default: 'text'
  85. },
  86. bgColor: {
  87. type: String,
  88. default: '#fff'
  89. },
  90. inputBgColor: {
  91. type: String,
  92. default: '#f0f0f0'
  93. },
  94. link: String,
  95. linkType: {
  96. type: String,
  97. default: 'navigateTo'
  98. },
  99. modelValue: String
  100. })
  101. const emits = defineEmits(['action', 'focus', 'blur', 'update:modelValue', 'change'])
  102. const handleChange = e => {
  103. emits('update:modelValue', e.detail.value)
  104. emits('change', e.detail.value)
  105. }
  106. const handleFocus = () => {
  107. emits('focus')
  108. }
  109. const handleBlur = () => {
  110. emits('blur')
  111. }
  112. const handleClear = () => {
  113. emits('update:modelValue', '')
  114. emits('change', '')
  115. }
  116. const handleAction = () => {
  117. emits('action', props.modelValue)
  118. }
  119. const handleLink = () => {
  120. if (props.link) {
  121. uni[props.linkType]({
  122. url: props.link
  123. })
  124. }
  125. }
  126. </script>
  127. <style lang="scss" scoped>
  128. .fs-search-box {
  129. width: 100%;
  130. height: 110rpx;
  131. padding: 20rpx var(--gutter);
  132. display: flex;
  133. background-color: #fff;
  134. box-sizing: border-box;
  135. align-items: center;
  136. }
  137. .fs-input-box {
  138. position: relative;
  139. height: 100%;
  140. width: 100%;
  141. flex: 1;
  142. background-color: #f0f0f0;
  143. .sub {
  144. line-height: 70rpx;
  145. color: var(--sub);
  146. }
  147. &.round {
  148. border-radius: 20px;
  149. .fs-input {
  150. border-radius: inherit;
  151. }
  152. }
  153. }
  154. .fs-input {
  155. height: 100%;
  156. width: 100%;
  157. padding-left: 68rpx;
  158. padding-right: 70rpx;
  159. border-radius: 6rpx;
  160. box-sizing: border-box;
  161. outline: none;
  162. /* #ifdef H5 */
  163. background-color: inherit;
  164. border: none;
  165. /* #endif */
  166. }
  167. .fs-cancel {
  168. margin-left: 20rpx;
  169. }
  170. .fs-icon {
  171. position: absolute;
  172. top: 50%;
  173. transform: translateY(-50%);
  174. color: var(--sub);
  175. z-index: 10;
  176. }
  177. .fs-icon-search {
  178. left: 20rpx;
  179. line-height: 1;
  180. }
  181. .fs-icon-close {
  182. right: 20rpx;
  183. }
  184. </style>