uni-search-bar.vue 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <template>
  2. <view class="uni-searchbar">
  3. <view :style="{borderRadius:radius+'px',backgroundColor: bgColor}" class="uni-searchbar__box" @click="searchClick">
  4. <view class="uni-searchbar__box-icon-search">
  5. <slot name="searchIcon">
  6. <uni-icons color="#999999" size="18" type="search" />
  7. </slot>
  8. </view>
  9. <input v-if="show || searchVal" :focus="showSync" :placeholder="placeholder" :maxlength="maxlength" class="uni-searchbar__box-search-input"
  10. confirm-type="search" type="text" v-model="searchVal" @confirm="confirm" @blur="blur" @focus="emitFocus" />
  11. <text v-else class="uni-searchbar__text-placeholder">{{ placeholder }}</text>
  12. <view v-if="show && (clearButton==='always'||clearButton==='auto'&&searchVal!=='')" class="uni-searchbar__box-icon-clear"
  13. @click="clear">
  14. <slot name="clearIcon">
  15. <uni-icons color="#c0c4cc" size="15" type="clear" />
  16. </slot>
  17. </view>
  18. </view>
  19. <text @click="cancel" class="uni-searchbar__cancel" v-if="cancelButton ==='always' || show && cancelButton ==='auto'">{{cancelText}}</text>
  20. </view>
  21. </template>
  22. <script>
  23. /**
  24. * SearchBar 搜索栏
  25. * @description 评分组件
  26. * @tutorial https://ext.dcloud.net.cn/plugin?id=866
  27. * @property {Number} radius 搜索栏圆角
  28. * @property {Number} maxlength 输入最大长度
  29. * @property {String} placeholder 搜索栏Placeholder
  30. * @property {String} clearButton = [always|auto|none] 是否显示清除按钮
  31. * @value always 一直显示
  32. * @value auto 输入框不为空时显示
  33. * @value none 一直不显示
  34. * @property {String} cancelButton = [always|auto|none] 是否显示取消按钮
  35. * @value always 一直显示
  36. * @value auto 输入框不为空时显示
  37. * @value none 一直不显示
  38. * @property {String} cancelText 取消按钮的文字
  39. * @property {String} bgColor 输入框背景颜色
  40. * @property {Boolean} focus 是否自动聚焦
  41. * @event {Function} confirm uniSearchBar 的输入框 confirm 事件,返回参数为uniSearchBar的value,e={value:Number}
  42. * @event {Function} input uniSearchBar 的 value 改变时触发事件,返回参数为uniSearchBar的value,e=value
  43. * @event {Function} cancel 点击取消按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
  44. * @event {Function} clear 点击清除按钮时触发事件,返回参数为uniSearchBar的value,e={value:Number}
  45. * @event {Function} blur input失去焦点时触发事件,返回参数为uniSearchBar的value,e={value:Number}
  46. */
  47. export default {
  48. name: "UniSearchBar",
  49. props: {
  50. placeholder: {
  51. type: String,
  52. default: "请输入搜索内容"
  53. },
  54. radius: {
  55. type: [Number, String],
  56. default: 5
  57. },
  58. clearButton: {
  59. type: String,
  60. default: "auto"
  61. },
  62. cancelButton: {
  63. type: String,
  64. default: "auto"
  65. },
  66. cancelText: {
  67. type: String,
  68. default: '取消'
  69. },
  70. bgColor: {
  71. type: String,
  72. default: "#F8F8F8"
  73. },
  74. maxlength: {
  75. type: [Number, String],
  76. default: 100
  77. },
  78. value: {
  79. type: [Number, String],
  80. default: ""
  81. },
  82. focus: {
  83. type: Boolean,
  84. default: false
  85. }
  86. },
  87. data() {
  88. return {
  89. show: false,
  90. showSync: false,
  91. searchVal: ''
  92. }
  93. },
  94. watch: {
  95. value: {
  96. immediate: true,
  97. handler(newVal) {
  98. this.searchVal = newVal
  99. if (newVal) {
  100. this.show = true
  101. }
  102. }
  103. },
  104. focus: {
  105. immediate: true,
  106. handler(newVal) {
  107. if (newVal) {
  108. this.show = true;
  109. this.$nextTick(() => {
  110. this.showSync = true
  111. })
  112. }
  113. }
  114. },
  115. searchVal(newVal, oldVal) {
  116. this.$emit("input", newVal)
  117. }
  118. },
  119. methods: {
  120. searchClick() {
  121. if (this.show) {
  122. return
  123. }
  124. this.show = true;
  125. this.$nextTick(() => {
  126. this.showSync = true
  127. })
  128. },
  129. clear() {
  130. this.$emit("clear", {
  131. value: this.searchVal
  132. })
  133. this.searchVal = ""
  134. },
  135. cancel() {
  136. this.$emit("cancel", {
  137. value: this.searchVal
  138. });
  139. this.searchVal = ""
  140. this.show = false
  141. this.showSync = false
  142. // #ifndef APP-PLUS
  143. uni.hideKeyboard()
  144. // #endif
  145. // #ifdef APP-PLUS
  146. plus.key.hideSoftKeybord()
  147. // #endif
  148. },
  149. confirm() {
  150. // #ifndef APP-PLUS
  151. uni.hideKeyboard();
  152. // #endif
  153. // #ifdef APP-PLUS
  154. plus.key.hideSoftKeybord()
  155. // #endif
  156. this.$emit("confirm", {
  157. value: this.searchVal
  158. })
  159. },
  160. blur() {
  161. // #ifndef APP-PLUS
  162. uni.hideKeyboard();
  163. // #endif
  164. // #ifdef APP-PLUS
  165. plus.key.hideSoftKeybord()
  166. // #endif
  167. this.$emit("blur", {
  168. value: this.searchVal
  169. })
  170. },
  171. emitFocus(e) {
  172. this.$emit("focus", e.detail)
  173. }
  174. }
  175. };
  176. </script>
  177. <style lang="scss" scoped>
  178. $uni-searchbar-height: 36px;
  179. .uni-searchbar {
  180. /* #ifndef APP-NVUE */
  181. display: flex;
  182. /* #endif */
  183. flex-direction: row;
  184. position: relative;
  185. padding: $uni-spacing-col-base;
  186. // background-color: $uni-bg-color;
  187. }
  188. .uni-searchbar__box {
  189. /* #ifndef APP-NVUE */
  190. display: flex;
  191. box-sizing: border-box;
  192. /* #endif */
  193. overflow: hidden;
  194. position: relative;
  195. flex: 1;
  196. justify-content: center;
  197. flex-direction: row;
  198. align-items: center;
  199. height: $uni-searchbar-height;
  200. padding: 5px 8px 5px 0px;
  201. border-width: 0.5px;
  202. border-style: solid;
  203. border-color: $uni-border-color;
  204. }
  205. .uni-searchbar__box-icon-search {
  206. /* #ifndef APP-NVUE */
  207. display: flex;
  208. /* #endif */
  209. flex-direction: row;
  210. // width: 32px;
  211. padding: 0 8px;
  212. justify-content: center;
  213. align-items: center;
  214. color: $uni-text-color-placeholder;
  215. }
  216. .uni-searchbar__box-search-input {
  217. flex: 1;
  218. font-size: $uni-font-size-base;
  219. color: $uni-text-color;
  220. }
  221. .uni-searchbar__box-icon-clear {
  222. align-items: center;
  223. line-height: 24px;
  224. padding-left: 8px;
  225. /* #ifdef H5 */
  226. cursor: pointer;
  227. /* #endif */
  228. }
  229. .uni-searchbar__text-placeholder {
  230. font-size: $uni-font-size-base;
  231. color: $uni-text-color-placeholder;
  232. margin-left: 5px;
  233. }
  234. .uni-searchbar__cancel {
  235. padding-left: 10px;
  236. line-height: $uni-searchbar-height;
  237. font-size: 14px;
  238. color: $uni-text-color;
  239. /* #ifdef H5 */
  240. cursor: pointer;
  241. /* #endif */
  242. }
  243. </style>