

為組(zu)件(jian)設置(zhi)一(yi)個容器,在容器中放置(zhi)搜索圖標、輸入框、清除文字按鈕(niu)和搜索按鈕(niu)。

<view class='container'>
<view class='input-wrapper'>
<image class='search-icon' src='/img/search.png'></image>
<input
placeholder='{{placeholder}}'
value='{{inputValue}}'
bindinput='handleInput'
bindconfirm='handleSearch'
bindfocus='inputFocused'>
</input>
<view class='close-icon-wrapper' wx:if="{{showCloseIcon}}" bindtap='clearValue'>
<image class='close-icon' src='/img/close.png' ></image>
</view>
<text bindtap='onTap'>搜索</text>
</view>
</view>
container:高度 100 rpx,背景色 #eee,flex 布局。
input-wrapper:高(gao)度 80 rpx,背(bei)景色(se) #fff,flex 布局,border-radius: 20rpx。
search-icon:寬(kuan)高(gao) 32 rpx。
input:字體和(he)光(guang)標顏色 #000,字體大小(xiao) 32 rpx。
close-icon-wrapper:寬高 80 rpx,絕(jue)對定位(wei)。
text:搜索按鈕寬 110 rpx,高(gao) 65 rpx,絕對(dui)定位(wei),左邊框 2rpx solid #eee。
.container {
background: #eee;
height: 100rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.input-wrapper {
display: flex;
align-items: center;
height: 80rpx;
width: 80%;
background: #fff;
border-radius: 20rpx;
}
.input-wrapper .search-icon {
margin-left: 20rpx;
width: 32rpx;
height: 32rpx;
}
.input-wrapper input {
margin-left: 10rpx;
color: #000;
font-size: 32rpx;
caret-color: #000;
width: 60%;
}
.input-wrapper .close-icon-wrapper{
position: absolute;
left: 480rpx;
width: 80rpx;
height: 80rpx;
background:#fff;
display: flex;
justify-content: center;
align-items: center;
}
.input-wrapper .close-icon {
width: 42rpx;
height: 42rpx;
}
.input-wrapper text {
position: absolute;
right: 80rpx;
width: 110rpx;
height: 65rpx;
padding: 0;
background: #fff;
display: flex;
justify-content: center;
align-items: center;
font-size: 32rpx;
border-left: 2rpx solid #eee;
}

組(zu)(zu)(zu)件的(de)構造器中(zhong)(zhong)要注意區分 properties 和 data,properties 中(zhong)(zhong)寫(xie)組(zu)(zu)(zu)件的(de)對(dui)外屬性,data 寫(xie)組(zu)(zu)(zu)件的(de)對(dui)內屬性。在(zai)本搜索(suo)組(zu)(zu)(zu)件中(zhong)(zhong) placeholder 和 value 從頁(ye)面傳來,所以它(ta)們寫(xie)在(zai) properties 中(zhong)(zhong),控制清除按鈕是(shi)否出現(xian)的(de) showCloseIcon 要寫(xie)在(zai) data 中(zhong)(zhong)。
properties: {
placeholder: {
type: String,
value: '搜索' // 如果頁面不傳placeholder,顯示“搜索”
},
inputValue: {
type: String
}
},
data: {
showCloseIcon: false,
},
(1)光標不聚焦,沒有任(ren)何輸入——顯示搜索圖標、placeholder和搜索按(an)鈕(niu)。
(2)光(guang)標(biao)聚焦,沒有任何輸入——光(guang)標(biao)閃爍,顯(xian)示(shi)搜(sou)索圖標(biao)、placeholder和(he)搜(sou)索按鈕。
(3)光(guang)標(biao)聚(ju)焦,有輸入——光(guang)標(biao)閃爍(shuo),顯示搜索圖標(biao)、輸入文字、清(qing)除按鈕(niu)和搜索按鈕(niu)。
(4)光標(biao)不聚焦,有輸(shu)入——顯示搜索圖標(biao)、輸(shu)入文字(zi)、清除按鈕和搜索按鈕。
(5)按(an)回車搜索——清除按(an)鈕隱藏。
(6)點擊(ji)搜索按(an)鈕——清除按(an)鈕隱藏。
由此可見,需要 input 組件的聚焦和鍵盤輸入事(shi)件。

<input
placeholder='{{placeholder}}'
value='{{inputValue}}'
bindinput='handleInput'
bindconfirm='handleSearch'
bindfocus='inputFocused'>
</input>
inputFocused:如果聚(ju)焦時,輸入框中有內容,顯示 closeIcon;
handleInput:如(ru)果(guo)輸入時沒有內容(rong),不(bu)顯(xian)示 closeIcon,有內容(rong),顯(xian)示 closeIcon 并把值存入 value。
handleSearch:點擊(ji)回車后,不顯示 closeIcon。
triggerEvent:自定義組件(jian)觸發(fa)事件(jian)時,需(xu)要使(shi)用(yong) triggerEvent 方(fang)法,指(zhi)定事件(jian)名、detail對(dui)象和事件(jian)選項。 文檔詳(xiang)情
inputFocused(e) {
if (e.detail.value !== '') {
this.setData({
showCloseIcon: true,
});
}
},
handleInput(e) {
if (e.detail.value == '') {
this.setData({
showCloseIcon: false,
});
} else {
this.setData({
showCloseIcon: true,
});
this.triggerEvent('handleInput', {
value: e.detail.value
});
}
},
handleSearch() { // 點擊鍵盤上的回車,調用此方法
this.setData({
showCloseIcon: false,
});
console.log('handleSearch', this.data.inputValue);
},
<view class='close-icon-wrapper' wx:if="{{showCloseIcon}}" bindtap='clearValue'>
<image class='close-icon' src='/img/close.png' ></image>
</view>
<text bindtap='onTap'>搜索</text>
分別為 closeIcon 和 搜索按鈕(niu)添加點擊事件(jian)。
clearValue() {
this.triggerEvent('handleInput', {
value: ''
});
this.setData({
showCloseIcon: false,
});
},
onTap() {
this.setData({
showCloseIcon: false,
});
console.log('onTap', this.data.inputValue);
},
{
"component":true
}
工程的名字(zi)是 cookbook,這里組件(jian)前綴統一為(wei) ck。
{
"usingComponents":{
"ck-input":"/components/search/index"
}
}
<view class='container'>
<ck-input
placeholder='搜你想吃的'
inputValue="{{inputValue}}"
bind:handleInput="handleInput">
</ck-input>
</view>
handleInput(e) {
this.setData({
inputValue: e.detail.value,
});
},
至(zhi)此,搜索組件已完(wan)成初步(bu)開發。