hookehuyr

refactor(SearchBar): 替换 NutUI Input 为原生 input 元素

重构 SearchBar 组件,移除对 NutUI Input 组件的依赖,改用原生 input 元素实现搜索输入框。这提高了组件的渲染性能并减少了包体积。同时,自定义了搜索图标和清除按钮的样式与交互逻辑,以获得更精细的 UI 控制。
<template>
<view class="search-bar" :class="containerClass">
<!-- NutUI Input 组件 -->
<nut-input
v-model="internalValue"
:type="inputType"
:placeholder="placeholder"
:disabled="disabled"
confirm-type="search"
:clearable="showClear"
:border="false"
class="search-input"
@clear="handleClear"
@blur="handleBlur"
@focus="handleFocus"
@confirm="handleSearch"
style="background: transparent;"
>
<template #left>
<view class="search-input-wrapper">
<!-- 左侧搜索图标 -->
<IconFont
name="search"
:size="iconSize"
:color="iconColor"
class="search-icon"
/>
<!-- 原生输入框 -->
<input
:value="internalValue"
:type="inputType"
:placeholder="placeholder"
:disabled="disabled"
confirm-type="search"
class="search-input"
@input="handleInput"
@focus="handleFocus"
@blur="handleBlur"
@confirm="handleSearch"
/>
<!-- 清除按钮 -->
<view
v-if="showClear && internalValue"
class="clear-icon"
@tap="handleClear"
>
<IconFont
name="search"
:size="iconSize"
:color="iconColor"
class="mr-[8rpx]"
name="close"
:size="14"
color="#9CA3AF"
/>
</template>
</nut-input>
</view>
</view>
</view>
</template>
......@@ -230,26 +241,75 @@ function handleClear() {
emit('clear')
emit('update:modelValue', '')
}
/**
* 处理输入事件(原生 input)
*/
function handleInput(e) {
const value = e.detail.value
internalValue.value = value
emit('update:modelValue', value)
emit('input', value)
}
</script>
<style lang="less">
.search-bar {
padding: 0;
background: white;
background: transparent;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
border-radius: 44rpx;
border: 1px solid #e5e7eb;
:deep(.nut-input) {
.search-input-wrapper {
display: flex;
align-items: center;
padding: 24rpx 32rpx;
background-color: transparent;
background: transparent;
border-radius: 44rpx;
.search-icon {
flex-shrink: 0;
margin-right: 16rpx;
}
.search-input {
flex: 1;
height: 100%;
font-size: 28rpx;
color: #333;
background: transparent;
border: none;
outline: none;
padding: 0;
margin: 0;
&::placeholder {
color: #9CA3AF;
}
&:disabled {
color: #ccc;
}
}
.clear-icon {
flex-shrink: 0;
margin-left: 16rpx;
padding: 8rpx;
cursor: pointer;
&:active {
opacity: 0.6;
}
}
}
&.search-bar-rounded {
border-radius: 44rpx;
overflow: hidden;
:deep(.nut-input) {
.search-input-wrapper {
border-radius: 44rpx;
}
}
......@@ -261,5 +321,9 @@ function handleClear() {
.search-bar-rounded {
height: 88rpx;
.search-input-wrapper {
height: 100%;
}
}
</style>
......