找了好多博客都没有找到关于小程序,模糊查询,自动联想,和关键字高亮显示的文章,没办法,自己造吧。
本文采用的是动态联想,即在input框中输入关键字后,将关键字作为条件去数据库查询,然后将所有查询结果以json格式返回给小程序的js文件,最后用关键字去匹配返回结果,并将结果中的关键字高亮显示。具体效果如下图所示:
不说其他废话了,直接上干货:
js
文件
// pages/search/search.js
Page({
data: {
// 模糊查询时长
timer: 0,
// 点击结果项之后替换到文本框的值
inputValue: '',
// 是否隐藏模糊查询的面板
hideScroll: true,
// 历史查询记录
historySearch: wx.getStorageSync('historySearch') || [],
// 模糊查询结果
searchTip: []
},
// onConfirm(e) {
// const keyword = e.detail.value
// console.log('keyword:', keyword)
// if (keyword) {
// this.addHistorySearch(keyword)
// this.searchByKeyWord(keyword)
// this.setData({
// keyword: keyword
// })
// }
// },
getInf(str, key) {
return str
.replace(new RegExp(`${key}`, 'g'), `%%${key}%%`)
.split('%%')
.filter(item => {
if (item) {
return true
}
return false
})
},
onInput(e) {
const inputValue = e.detail.value
clearTimeout(this.data.timer)
let timer = setTimeout(() => {
if (inputValue) {
// 如果输入的关键字不为空,则发起请求获取联想值
const tips = [
{ tip: '城市', content: '北京' },
{ tip: '大学', content: '北京大学' },
{ tip: '专业', content: '北京测绘工程' }
]
const newTips = tips.map(item => {
const { tip, content } = item
const newContent = this.getInf(content, inputValue)
return { tip, content: newContent }
})
console.log('newTips:', newTips)
this.setData({
inputValue: inputValue,
searchTip: newTips,
hideScroll: false
})
return
}
// 如果为空,则收起
this.setData({
searchTip: [],
hideScroll: true,
inputValue: ''
})
}, 600)
this.data.timer = timer
},
itemtap(e) {
const { info } = e.currentTarget.dataset
this.setData({
// 将点击选择的值展示在input框中
inputValue: info.content.join(''),
// 当用户选择某个联想词,隐藏下拉列表
hideScroll: true
})
this.addHistorySearch(info)
// 发起请求,获取查询结果
this.searchByKeyWord(info)
},
searchByKeyWord(info) {
// 发起请求,获取面板数据
},
addHistorySearch(value) {
const historySearch = wx.getStorageSync('historySearch') || []
// 是否有重复的历史记录
let has = false
for (let history of historySearch) {
const { content } = history
if (value.content === content) {
has = true
break
}
}
if (has) {
return
}
const len = historySearch.length
if (len >= 8) {
historySearch.pop()
}
historySearch.unshift(value)
wx.setStorage({
key: 'historySearch',
data: historySearch,
success: () => {
this.setData({ historySearch: historySearch })
}
})
}
})
wxml
文件:
<wxs src="../../utils/utils.wxs" module="util" />
<view>
<view class="seachBar">
<image src="/images/search.png" style="width:40rpx;height:40rpx" />
<input value="{{inputValue}}" focus='true' confirm-type="search" placeholder="搜索感兴趣的城市、大学、专业" bindinput="onInput" />
</view>
<view class="line"></view>
<view class="search-box" wx:if="{{!inputValue&&historySearch.length>0}}">
<view class="border-title">历史搜索</view>
<view class="search-content">
<block wx:for="{{historySearch}}" wx:key="*this">
<view class="search-item">{{util.join(item.content)}}</view>
</block>
</view>
</view>
<scroll-view scroll-y="true" class="search-res" hidden="{{hideScroll}}">
<view class="sum">共找到和“{{inputValue}}”相关的结果{{searchTip.length}}个</view>
<block wx:for="{{searchTip}}" wx:key="content">
<view class="tip-item" bindtap="itemtap" data-info="{{item}}">
<view class="left">
<view class="tip">{{item.tip}}</view>
<view class="content">
<view wx:for="{{item.content}}" wx:for-item="textItem" wx:key="{{index}}" class="{{textItem == inputValue ? 'searchHigh' : '' }}">
{{textItem}}
</view>
</view>
</view>
<image src="/images/right.png" style="width:36rpx;height:36rpx" />
</view>
</block>
</scroll-view>
</view>
wxss
文件:
/* pages/search/search.wxss */
.seachBar {
display: flex;
flex-direction: row;
padding-left: 34rpx;
}
.seachBar input {
margin-left: 18rpx;
}
.line {
box-sizing: border-box;
border: 2rpx solid rgba(235, 235, 235, 1);
margin-top: 28rpx;
margin-left: 40rpx;
margin-right: 40rpx;
}
.search-box {
margin-top: 50rpx;
margin-left: 40rpx;
}
.border-title {
font-size: 36rpx;
font-weight: 400;
color: rgba(51, 51, 51, 1);
}
.search-content {
display: flex;
flex-direction: row;
margin-top: 2rpx;
flex-wrap: wrap;
margin-right: -30rpx;
/* margin-top: -30rpx; */
}
.search-item {
/* width: 160rpx; */
padding-left: 28rpx;
padding-right: 28rpx;
line-height: 62rpx;
background: rgba(245, 245, 245, 1);
border-radius: 12rpx;
text-align: center;
margin-right: 30rpx;
margin-top: 30rpx;
}
.sum {
margin-bottom: 20rpx;
margin-top: 20rpx;
}
.tip-item {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 144rpx;
border-bottom: 2rpx solid rgba(235, 235, 235, 1);
}
.left {
display: flex;
flex-direction: row;
align-items: center;
}
.tip {
width: 64rpx;
line-height: 38rpx;
text-align: center;
background: rgba(245, 245, 245, 1);
border-radius: 6px;
font-size: 24rpx;
font-weight: 400;
color: rgba(102, 102, 102, 1);
}
.content {
display: flex;
font-size: 32rpx;
font-weight: 400;
line-height: 44rpx;
color: rgba(51, 51, 51, 1);
margin-left: 22rpx;
}
.search-res {
box-sizing: border-box;
padding-left: 40rpx;
padding-right: 40rpx;
}
.searchHigh {
color: #37C2BC;
}
注释比较清楚了,多看几遍就懂了,关键字高亮的思想就是,将需要展示的文本,根据关键字进行拆成数组,然后再根据关键字判断是否需要高亮。如果有不懂的可以加我微信qdw1370336125相互交流。