今天说一下小程序首页的搜索功能吧
这个搜索功能我是建了一个组件,用组件写的:
上代码:
wxml代码
<view class="search">
<input placeholder="输入搜索关键词" type="text" class="search_input" data-value="value" bindconfirm="search"></input>
<image src="/assets/search.png" class="search_img"></image>
</view>
js代码:
// components/zj_search/zj_search.jsz
Component({
/**
* 组件的属性列表
*/
properties: {
},
/**
* 组件的初始数据
*/
data: {
},
/**
* 组件的方法列表
*/
methods: {
search: function (e) {
// 拿到输入框的值
var value = e.detail.value
// console.log(value);
wx.navigateTo({
url: `/pages/zj_detail_search/zj_detail_search?value=${value}`
})
}
}
})
css代码:
/* components/zj_search/zj_search.wxss */
.search{
border: 1rpx solid gainsboro;
border-radius: 20rpx;
display: flex;
position: absolute;
top: 20rpx;
width: 90%;
height: 50rpx;
line-height: 70rpx;
padding: 10rpx;
left: 27rpx;
z-index: 2;
background: rgba(248, 245, 245, 0.5);
}
.search_input{
width: 690rpx;
/* border: 1rpx solid red; */
height: 50rpx;
line-height: 60rpx;
padding-left: 20rpx;
}
.search .search_img{
z-index: 1;
width: 40rpx;
height: 40rpx;
/* margin-left: 240rpx; */
margin-top: 7rpx;
}
以上搜索组件就建好了,绑了一个value值,添加了一个事件。
搜索 点进来之后会跳到这个页面,先不说别的,会看见搜索框右边有一个切换图标,点击会切换样式,大概就是下面这样 :
然后我就写了两套布局,两套样式,用最原始的点击显示隐藏的办法完成这个功能:
代码如下:
wxml代码
<!--pages/zj_detail_search/zj_detail_search.wxml-->
<!--components/zj_search/zj_search.wxml-->
<view class="box">
<view class="search_box">
<view class="search">
<input placeholder="输入搜索关键词" type="text" class="search_input" value="{{name}}" data-name="name" bindconfirm="search"></input>
<image src="/assets/search.png" class="search_img"></image>
</view>
<view class="switch" catchtap="clicka" hidden="{{hiddenimga}}">
<image src="../../assets/a.png"></image>
</view>
<view class="switch" catchtap="clickb" hidden="{{hiddenimgb}}">
<image src="../../assets/b.png"></image>
</view>
</view>
<!-- tab切换 -->
<view class="tab_list">
<view wx:for="{{tabList}}" wx:key="item.id" class="{{ index===currentIndex? 'active':'' }}" catchtap="changeTab" data-index="{{ index }}">
<view class="tab_content">{{item.tabName}}</view>
</view>
</view>
<!-- 布局1 -->
<view hidden="{{hiddena}}" wx:for="{{searchList}}" wx:key="index" wx:if="sell" catchtap="goDetails" data-id="{{item.id}}">
<view class="search_list_content1">
<view class="search_list_image1">
<image src="{{item.pic}}"></image>
</view>
<view class="text">
<view class="search_list_title1">{{item.name}}</view>
<view class="search_list_price1">¥{{item.minPrice}}</view>
<view class="search_list_sell1">已售出{{item.numberSells}}件</view>
</view>
<view class="search_list_car1">
<image src="/assets/cart_active.png"></image>
</view>
</view>
</view>
<!-- 布局2 -->
<view class="box2">
<view hidden="{{hiddenb}}" wx:for="{{searchList}}" wx:key="index" catchtap="goDetails" data-id="{{item.id}}">
<view class="search_list_content2">
<view class="search_list_image2">
<image src="{{item.pic}}" class="searchList_image2"></image>
</view>
<view class="search_list_title2">{{item.characteristic}}</view>
<view class="search_list_price2">¥{{item.minPrice}}</view>
<view class="search_list_sell2">已售出{{item.numberSells}}件</view>
<view class="search_list_car2">
<image src="/assets/cart_active.png"></image>
</view>
</view>
</view>
</view>
</view>
js代码:
// pages/zj_detail_search/zj_detail_search.js
const {
zj_api
} = require("../../http/api");
Page({
/**
* 页面的初始数据
*/
data: {
// value: "", //输入框的值
name: '', //与首页相绑定的值
hiddenb: true,
hiddena: false,
hiddenimga: true,
hiddenimgb: false,
searchList: [], //所有的商品列表数据
showList: [], //保存的商品列表的数据(就是25条数据,为了销量和排序的遍历)
// selectIndex:"",//下标
// sell: [],
currentIndex: 0,
tabList: [{
id: 1001,
tabName: '综合'
},
{
id: 1002,
tabName: '新品'
},
{
id: 1003,
tabName: '销量'
},
{
id: 1004,
tabName: '价格'
},
],
},
// 搜索
search: function (e) {
let value = e.detail.value
zj_api("goodsItem").then(res => {
this.data.searchList = []
res.data.forEach(ele => {
if (ele.name.includes(value)) {
this.data.searchList.push(ele)
}
})
this.setData({
searchList: this.data.searchList,
name: value,
showList: res.data
})
})
},
// 样式显示隐藏
clicka: function (e) {
this.setData({
hiddena: !this.data.hiddena,
hiddenb: !this.data.hiddenb,
hiddenimga: !this.data.hiddenimga,
hiddenimgb: !this.data.hiddenimgb,
})
},
clickb: function (e) {
this.setData({
hiddenb: !this.data.hiddenb,
hiddena: !this.data.hiddena,
hiddenimga: !this.data.hiddenimga,
hiddenimgb: !this.data.hiddenimgb,
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
let val = options.value;
zj_api("goodsItem").then(res => {
// console.log(res.data)
res.data.forEach(ele => {
if (ele.name.includes(val)) {
this.data.searchList.push(ele)
}
})
this.setData({
searchList: this.data.searchList,
name: val,
showList: res.data
})
})
},
changeTab(e) {
let index = e.currentTarget.dataset.index
this.setData({
currentIndex: index
})
// 价格排序
if (index == "3") {
this.data.searchList.sort((a, b) => {
return a.minPrice - b.minPrice
})
this.setData({
searchList: this.data.searchList
})
// 销量排序
} else if (index == "2") {
this.data.searchList.sort((a, b) => {
return b.numberSells - a.numberSells
})
this.setData({
searchList: this.data.searchList
})
//新品排序
} else if (index == "1") {
this.data.searchList.forEach(ele => {
// console.log(ele.dateStart);
var arr = [ele.dateStart];
// console.log(arr)
Array.prototype.sortFn = function () {
var arr2 = []
var json = {};
for (var index = 0, len = this.length; index < len; index++) {
json[new Date(this[index]).getTime()] = this[index];
arr2.push(new Date(this[index]).getTime());
}
arr2.sort();
for (var j = 0; j < arr2.length; j++) {
this[j] = json[arr2[j]];
}
return this;
}
// console.log(arr.sortFn())
})
this.setData({
searchList: this.data.searchList
})
//综合排序
} else if (index == "0") {
// console.log(this.data.name)
zj_api("goodsItem").then(res => {
this.data.searchList = [];
res.data.forEach(ele => {
if (ele.name.includes(this.data.name)) {
this.data.searchList.push(ele)
}
})
this.setData({
searchList: this.data.searchList,
name: this.data.name,
showList: res.data
})
})
}
},
goDetails(e) {
let id = e.currentTarget.dataset.id;
console.log(id)
wx.navigateTo({
url: '../../pages/details/details?id=' + id,
})
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
// this.search()
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})
css代码
/* pages/zj_detail_search/zj_detail_search.wxss */
/* components/zj_search/zj_search.wxss */
.box {
width: 100%;
height: 100%;
background: #F5F5F5;
z-index: 666;
}
.search_box {
height: 132rpx;
background: #FFFFFF;
}
.search {
border: 1rpx solid gainsboro;
border-radius: 20rpx;
display: flex;
position: absolute;
top: 20rpx;
width: 80%;
height: 50rpx;
line-height: 70rpx;
padding: 10rpx;
left: 32rpx;
z-index: 2;
background: #FFFFFF;
}
.search_input {
/* border: 1rpx solid red; */
width: 540rpx;
height: 50rpx;
line-height: 60rpx;
padding-left: 20rpx;
}
.search .search_img {
z-index: 1;
width: 40rpx;
height: 40rpx;
/* margin-left: 170rpx; */
margin-top: 7rpx;
}
.switch {
position: absolute;
top: 30rpx;
right: 27rpx;
}
.switch image {
width: 50rpx;
height: 50rpx;
z-index: 3;
}
.tab_list {
border-top: 1rpx solid gainsboro;
display: flex;
justify-content: space-around;
background: #FFFFFF;
height: 90rpx;
width: 100%;
line-height: 90rpx;
}
.searchList_image {
border: 1rpx solid red;
z-index: 5;
}
/* 样式1 */
.search_list_content1 {
display: flex;
background: #FFFFFF;
width: 96%;
height: 275rpx;
border-radius: 20rpx;
margin-top: 20rpx;
margin-left: 17rpx;
}
.search_list_image1 image {
width: 260rpx;
height: 275rpx;
border-radius: 20rpx;
/* padding: 15rpx; */
}
.text {
width: 400rpx;
padding-left: 30rpx;
}
.search_list_title1 {
font-size: 30rpx;
margin-top: 20rpx;
}
.search_list_price1 {
font-size: 40rpx;
color: red;
}
.search_list_sell1 {
font-size: 30rpx;
color: #9E9E9E;
}
.search_list_car1 {
width: 70rpx;
height: 70rpx;
}
.search_list_car1 image {
width: 50rpx;
height: 50rpx;
margin-top: 170rpx;
}
/* 样式2 */
.search_list_content2 {
position: relative;
background: #FFFFFF;
width: 47%;
height: 600rpx;
float: left;
margin-top: 30rpx;
margin-left: 15rpx;
border-radius: 20rpx;
}
.search_list_image2 image {
width: 100%;
height: 353rpx;
border-radius: 20rpx;
}
.search_list_title2 {
font-size: 30rpx;
margin-left: 20rpx;
}
.search_list_price2 {
font-size: 35rpx;
color: red;
margin-left: 20rpx;
}
.search_list_sell2 {
font-size: 25rpx;
color: #9E9E9E;
margin-left: 20rpx;
}
.search_list_car2 image {
width: 50rpx;
height: 50rpx;
position: absolute;
bottom: 15rpx;
right: 10rpx;
}
/* tab切换 */
.active {
color: red;
}
.box2{
width: 100%;
height: 8500rpx;
background: #F5F5F5;
z-index: 999;
}
在要切换的图标上绑定方法事件,在js data里面定义显示隐藏的属性,然后让事件点击后显示隐藏切换样式就可以了。
然后看下面的功能,有四个tab切换:
tab切换动态样式这块(就给大家分享一个好链接,写的很清楚):
搜索逻辑这块,首先要获取到input的value值,然后把接口数据调出来之后,用forEach方法遍历要循环的数组,把获取到的input的value值用includes方法找到与他相匹配的字段,然后让一个数组把对应与他相匹配的字段接住,渲染到页面就可以了,具体代码上面都有。
然后就是排序这一块,用匹配下标的方法让它们显示对应的数据,比如综合的下标为0,就让他显示全部的数据,新品的下标为1,就让他显示对应新品的数据,销量的下标为2,就显示对应销量的数据,,价格的下标为3,就让它显示对应价格的数据。代码上面都有。
然后,看见分类页面也有搜索框:
因为前面搜索框是用组件写的,所以直接在页面引入组件标签就可以了
注意在json里面引入组件
这样分类页面也可以正常搜索了。