我們先來看一下實作哪些功能:
1 搜尋曆史記錄以及清空曆史記錄
2 熱門搜尋推薦以及更新推薦内容
3 根據輸入框輸入的内容來自動搜尋相關查詢,背景邏輯是模糊查詢,背景就先不扯了
這裡我用的是自己定義的虛拟資料,暫時沒用背景接口,可能有點問題,希望大家指出,共同解決,一起進步
好了廢話就不多說了,我們先看看代碼吧
wxml
<!-- 自定義頂部導航 S -->
<view class="navbar custom-class" style='height:{{navHeight}}px;'>
<view class="navbar-action-wrap navbar-action-group row item-center" style='top:{{navTop}}px;'>
<image style="width: 1rem; height: 1.2rem; " src="{{leftIcon}}" catchtap="goBack"></image>
</view>
<view class='navbar-title' style='top:{{navTop}}px'>
<view class="search-input">
<span class="search-con">
<view class="center-30f2b4d">
<!-- 自定義區域 -->
<image class="icon" src="{{searchIcon}}" catchtap="searchbegin" data-postname="{{inputValue}}"></image>
<input class="search-size" confirm-type="search" value="{{inputValue}}" type="text" bindinput="getInputValue" placeholder="搜尋品牌或商品" placeholder-class="phcolor"></input>
</view>
</span>
</view>
</view>
</view>
<!-- 自定義頂部導航 E -->
<view class="read-in">
<!-- 最近搜尋 S -->
<view class="headline" wx:if="{{historyStorage.length!=0}}" hidden="{{historyStorageShow?false:true}}">
<view class="head-headline justify">
<view class="headline-size">最近搜尋</view>
<view class="right size" catchtap="remove">清除</view>
</view>
<!-- 最近搜尋内容 S -->
<view class="lately-main">
<view class="chunk" wx:for="{{historyStorage}}" wx:key="index" bindtap='routeToSearchResPage' data-index='{{index}}'>
<text>{{item}}</text>
</view>
</view>
<!-- 最近搜尋内容 E -->
</view>
<!-- 最近搜尋 E -->
<!-- 熱門搜尋 S -->
<view class="headline">
<view class="head-headline">
<view class="headline-size">熱門搜尋</view>
<view class="liang">
<view class="low-bo">
<image class="icon-eye low-bottom" bindtap="reye" src="{{eyeIconOne}}" hidden="{{!eye}}"></image>
<image class="icon-eye low-bottom" bindtap="reye" src="{{eyeIcon}}" hidden="{{eye}}"></image>
</view>
<view class="right size" bindtap="changeother">換一批</view>
</view>
</view>
<!-- 熱門推薦内容 S -->
<view class="lately-main" hidden="{{eye?false:true}}">
<view class="chunk" wx:for="{{falg ? hotsearch1 : hotsearch2}}" wx:key="index">
<text>{{item.title}}</text>
</view>
</view>
<!-- 熱門推薦内容 E -->
</view>
<!-- 熱門搜尋 E -->
</view>
<!--搜尋結果-->
<view class="searchresult" wx:if="{{inputValue != ''}}" hidden="{{searchresult?false:true}}">
<view class="result" wx:for="{{searchResult}}" catchtap="searchbegin" wx:key="index" bindtap="getInputValue" data-postname="{{item.result}}">
<view>{{item.result}}</view>
<image src="{{upperLeftArrow}}"></image>
</view>
</view>
大家應該都能看懂吧,可能有人就會問了
<view class="result" wx:for="{{searchResult}}" catchtap="searchbegin" wx:key="index" bindtap="getInputValue" data-postname="{{item.result}}">
<view>{{item.result}}</view>
<image src="{{upperLeftArrow}}"></image>
</view>
為什麼這個wx:for用了兩個點選事件,catchtap和bindtap,如果用兩個catchtap或者bindtap可不可以,這裡我就告訴你,不可以,親測,會有沖突
我們先回顧一下catchtap和bindtap差別:
- DOM模型是一個樹形結構,在DOM模型中,HTML元素是有層次的。當一個HTML元素上産生一個事件時,該事件會在DOM樹中元素節點與根節點之間按特定的順序傳播,路徑所經過的節點都會收到該事件,這個傳播過程就是DOM事件流。
- JS冒泡事件:當一個元素上的事件被觸發的時候,比如說滑鼠點選了一個按鈕,同樣的事件将會在那個元素的(所有祖先元素)中被觸發。這 一過程被稱為事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層
共同點:
在微信小程式的事件機制中,bindtap和catchtap都可以觸發一個元件的點選事件
差別:
bindtap不能阻止事件冒泡
catchtap可以阻止事件冒泡
wxss
page {
background: white;
}
.navbar {
width: 100%;
overflow: hidden;
position: fixed;
top: 0;
left: 0;
z-index: 10;
flex-shrink: 0;
background-color: white;
}
.navbar-title {
width: 100%;
box-sizing: border-box;
padding-left: 40px;
padding-right: 120px;
height: 33px;
line-height: 33px;
position: fixed;
left: 0;
z-index: 10;
color: #333;
font-size: 16px;
font-weight: bold;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
display: flex;
}
.navbar-action-wrap {
display: -webkit-flex;
display: flex;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
left: 10px;
z-index: 11;
line-height: 1;
padding-top: 4px;
padding-bottom: 4px;
position: fixed;
}
.navbar-action-group {
border-radius: 20px;
overflow: hidden;
}
.navbar-action_item {
padding: 3px 0;
color: #333;
}
.navbar-action-group .navbar-action_item {
border-right: 1px solid #f0f0f0;
padding: 3px 14px;
}
.navbar-action-group .last {
border-right: none;
}
.navbar-title-size {
font-size: 10px;
margin-right: 20rpx;
align-self: center;
margin: 0 auto;
}
.navbar-title-size.active {
color: red;
border-bottom: 2px solid red;
}
.scroll-box {
position: absolute;
height: 100%;
}
.search-input {
width: 100%;
height: 28px;
line-height: 28px;
background: #f6f6f6;
border-radius: 30rpx;
/* margin-top: 2px; */
font-size: 25rpx;
}
.search-con {
display: flex;
align-items: center;
}
.search-con .center-30f2b4d {
height: 28px;
line-height: 28px;
flex: 1;
display: flex;
align-items: center;
}
.search-con .center-30f2b4d .icon {
width: 15px;
height: 15px;
align-self: center;
margin: 0 10px;
}
.search-con .center-30f2b4d .search-size {
width: 60%;
font-size: 12px;
font-family: "微軟雅黑";
}
.phcolor {
color: #D3D3D3;
}
/* nav E */
/* 标題部分 */
.read-in {
margin-top: 64px;
padding: 0 40rpx;
}
.headline {
padding-top: .5rem;
}
.head-headline {
width: 100%;
height: 45rpx;
position: relative;
display: flex;
}
.liang {
width: 100%;
display: flex;
justify-content: space-between;
}
.justify {
display: flex;
justify-content: space-between;
}
.headline-size {
width: 185rpx;
font-size: 35rpx;
float: left;
}
.low-bo {
/* flex: 1; */
height: 45rpx;
position: relative;
align-self: center;
}
.low-bottom {
/* position:absolute; */
bottom:0px;
padding:0 10rpx 0;
margin:0px;
}
.size {
/* flex: 1; */
float: right;
font-size: 30rpx;
color: #d4237a;
/* position: absolute; */
bottom:0px;
align-self: center;
}
/* 内容部分 */
.lately-main {
margin-top: 20rpx;
overflow: hidden;
}
.lately-main .chunk {
display: inline-block;
font-size: 25rpx;
line-height: 20rpx;
padding: 20rpx 20rpx;
background: #f5f5f5;
margin-right: 30rpx;
border: 1px solid #DCDCDC;
border-radius: 30rpx;
margin-bottom: 30rpx;
float: left;
}
.searchresult {
margin-top: 20px;
position: absolute;
top: 55px;
left: 0;
width: 100%;
background: #fff;
}
.result {
height: 50px;
line-height: 50px;
text-align: left;
border-bottom: 1px solid #eee;
padding: 0 30rpx;
color: #333;
font-family: "微軟雅黑";
font-size: 30rpx;
display: flex;
align-items: center;
justify-content: space-between;
}
.result image {
width: 50rpx;
height: 50rpx;
}
css就不用說太多了吧,不過有個小bug,我在調試的時候發現的,不過很好解決,這裡就不多說了
js
const App = getApp()
Page({
/**
* 頁面的初始資料
*/
data: {
// 自定義頂部導航
navHeight: App.globalData.navHeight,
navTop: App.globalData.navTop,
// 圖示
leftIcon: "../../../img/icon/icon-left.png",
searchIcon: "../../../img/icon/icon-search.png",
eyeIconOne: "../../../img/icon/icon-eye-one.png",
eyeIcon: "../../../img/icon/icon-eye.png",
upperLeftArrow: "../../../img/icon/icon-upper-left-arrow.png",
recommend: [ //熱門推薦
{
title: "冰箱"
},
{
title: "紅魔手機"
},
{
title: "洗衣機"
},
{
title: "電視機"
},
{
title: "冰箱 雙門"
},
{
title: "海爾洗衣機 滾筒"
},
{
title: "手機自營"
},
{
title: "小天鵝洗衣機全自動"
},
{
title: "手機"
},
{
title: "筆記本"
}
],
historyStorage: [], //曆史搜尋
historyStorageShow: false,
falg: true, //換一批
hotsearch1: [{ title: "短褲" }, { title: "背帶裙" }, { title: "牛仔褲男" }, { title: "運動 休閑男鞋" }, { title: "蕾絲連衣裙" }, { title: "電視" }, { title: "長裙" }, { title: "oppo" }, { title: "藍牙耳機" }, { title: "女包" }, { title: "格力空調" }, { title: "魅族" }],
hotsearch2: [{ title: "平闆電腦" }, { title: "耳機" }, { title: "男鞋" }, { title: "iPhone" }, { title: "蕾絲連衣裙" }, { title: "電視" }, { title: "長裙" }, { title: "oppo" }, { title: "藍牙耳機" }, { title: "女包" }, { title: "格力空調" }, { title: "魅族" }],
// searchresult: false,
inputValue: "", //輸入框輸入的值
replaceValue: "", //替換輸入框的值
eye: true, //顯示隐藏
searchresult: false,
searchResult: [{ result: "蘋果手機" }, { result: "手機支架" }, { result: "手機自營" }, { result: "手機套" }, { result: "手機膜" }, { result: "手機卡" }, { result: "手機報" }, { result: "蘋果手機殼" }, { result: "手機車載支架" }]//虛拟的查詢結果
},
// 點選傳回上一級
goBack: function() {
let pages = getCurrentPages(); //擷取小程式頁面棧
let beforePage = pages[pages.length - 2]; //擷取上個頁面的執行個體對象
beforePage.setData({
txt: "修改資料了"
})
beforePage.goUpdate(); //觸發上個頁面自定義的go_update()方法
wx.navigateBack({
delta: 1
})
},
/**
* 擷取頂部固定高度
*/
attached: function() {
this.setData({
navHeight: App.globalData.navHeight,
navTop: App.globalData.navTop,
})
},
/**
* 換一批操作
*/
changeother: function () {
this.setData({
falg: !this.data.falg
})
},
/**
* 熱門搜尋顯示隐藏
*/
reye: function () {
this.setData({
eye: !this.data.eye
})
},
/**
* 清除
*/
remove: function () {
var _this = this
wx: wx.showModal({
content: '确認清除所有曆史記錄?',
success: function (res) {
if (res.confirm) {
wx: wx.removeStorage({
key: 'historyStorage',
success: function (res) {
_this.setData({
historyStorage: []
})
wx.setStorageSync("historyStorage", [])
},
})
} else {
console.log("點選取消")
}
},
})
},
/**
* 擷取input的值
*/
getInputValue(e) {
// console.log("擷取value值",e.detail) // {value: "ff", cursor: 2}
this.setData({
inputValue: e.detail.value
})
this.setData({
searchresult: true,
})
},
/**
* 點選搜尋送出跳轉并存儲曆史記錄
*/
searchbegin: function (e) {
let _this = this
var data = e.currentTarget.dataset;
_this.data.replaceValue = e.currentTarget.dataset.postname
// _this.data.replaceValue =
wx: wx.setStorage({
key: 'historyStorage',
data: _this.data.historyStorage.concat(_this.data.inputValue),
data: _this.data.historyStorage.concat(_this.data.replaceValue)
})
// console.log(_this.data.inputValue)
// console.log(_this.data.historyStorage)
wx.navigateTo({
url: '../../commodity/commodity-search-list/index?postName=' + data['postname']
})
},
/**
* 生命周期函數--監聽頁面加載
*/
onLoad: function(options) {
// 曆史搜尋
let that = this
wx.getStorage({
key: 'historyStorage',
success: function (res) {
console.log(res.data)
that.setData({
historyStorageShow: true,
historyStorage: res.data
})
}
})
},
//點選進入詳情頁
goToList: function (e) {
},
goUpdate: function() {
this.onLoad()
console.log("我更新啦")
},
/**
* 生命周期函數--監聽頁面初次渲染完成
*/
onReady: function() {
},
/**
* 生命周期函數--監聽頁面顯示
*/
onShow: function() {
},
/**
* 生命周期函數--監聽頁面隐藏
*/
onHide: function() {
},
/**
* 生命周期函數--監聽頁面解除安裝
*/
onUnload: function() {
},
/**
* 頁面相關事件處理函數--監聽使用者下拉動作
*/
onPullDownRefresh: function() {
},
/**
* 頁面上拉觸底事件的處理函數
*/
onReachBottom: function() {
},
/**
* 使用者點選右上角分享
*/
onShareAppMessage: function() {
}
})
js基本上都有備注,這裡就不說太多了,我就說一下這個函數吧
searchbegin: function (e) {
let _this = this
var data = e.currentTarget.dataset;
_this.data.replaceValue = e.currentTarget.dataset.postname
// _this.data.replaceValue =
wx: wx.setStorage({
key: 'historyStorage',
data: _this.data.historyStorage.concat(_this.data.inputValue),
data: _this.data.historyStorage.concat(_this.data.replaceValue)
})
// console.log(_this.data.inputValue)
// console.log(_this.data.historyStorage)
wx.navigateTo({
url: '../../commodity/commodity-search-list/index?postName=' + data['postname']
})
},
自定義的data在點選執行這個函數的時候擷取input框輸入的value值,這個應該都明白吧
_this.data.replaceValue這個是在data裡面定義了一個變量名為replaceValue,然後将e.currentTarget.dataset.postname擷取到的值指派給replaceValue,下面的就不用多說了吧,将拿到的值存儲到historyStorage空清單裡面,下面的是點選搜尋跳轉到的結果清單
最後給大家看一下效果圖吧
