我们先来看一下实现哪些功能:

1 搜索历史记录以及清空历史记录

2 热门搜索推荐以及更新推荐内容

3 根据输入框输入的内容来自动搜索相关查询,后台逻辑是模糊查询,后台就先不扯了

这里我用的是自己定义的虚拟数据,暂时没用后台接口,可能有点问题,希望大家指出,共同解决,一起进步

好了废话就不多说了,我们先看看代码吧

wxml

最近搜索

清除

{{item}}

热门搜索

换一批

{{item.title}}

{{item.result}}

大家应该都能看懂吧,可能有人就会问了

{{item.result}}

为什么这个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空列表里面,下面的是点击搜索跳转到的结果列表

最后给大家看一下效果图吧

很简单,也很繁琐,不过还是看项目设计,这样用户体验很不错

如果对你有帮助希望关注一下,多多支持,有什么问题可以下方留言共同学习

如果对你有用,关注一下博主的小程序,登录一下给予支持,以后有什么开源好用的源码都会上传到小程序