<
template>
<view class="container">
<van-search
id="searchPanel"
value="{{ searchValue }}"
placeholder="请输入搜索关键词"
bind:change="inpChange"
<view class="statistic-bar">
<text>第{{ current }}条</text>
<text>共{{ totalKeywordNodes }}条</text>
<text style="color: #1d84f6" bindtap="handleScroll('pre')">上一条</text>
<text style="color: #1d84f6" bindtap="handleScroll('next')">下一条</text>
</view>
<scroll-view scroll-y enhanced style="height: {{listHeight}}px" class="listPanel">
<view class="news_item" wx:for="{{newList}}" wx:key="index">
<view class="descBox">
<view class="news_title textoverflow">{{ item.title }}</view>
<view class="news_text">
wx:for="{{ item.jj }}"
wx:for-index="secondIndex"
wx:key="secondIndex"
id="text_{{index + '_'+ secondIndex}}"
class="{{ item == searchValue ? 'searchHigh' : ''}}"
wx:class="{{ {selected: 'text_'+index + '_'+ secondIndex === keywordNodes[activeNodeIndex]} }}"
>{{ item }}</text
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<script>
import { createPage } from '@mpxjs/core'
createPage({
data: {
mainHeight: 0,
seachPanelHeight: 0,
searchValue: '',
scrollView: null,
newList: [
title: '关于举行机器人竞赛活动的相所发生的方式胜多负少的',
jj: '内容简介中央气象台气温气温UIuouoiuo水电费水电费公司的发生的对方水电费'
title: '关偶奇偶我奇偶就hi呕吼我和奇偶以后后的',
jj: '内kjlkjljk防守打法你是端放开那没事的离开父母了情况没考虑为全面方水电费'
title: '关于额外日围殴日头诶让你偷Irene的',
jj: '内容简介中央气象台发布寒潮蓝色预警计今天20时至8日20时水电费水电费水电费公司的发生的对方水电费'
title: '关于尔特瑞特认同与一体uyiuyiuyiuyiiuoui 胜多负少的',
jj: '内容简介我解耦我偶奇偶我我就挨打王企鹅卖家前往颇尔恶趣味驱蚊器翁群水电费'
keywordNodes: [],
activeNodeIndex: 0
computed: {
listHeight () {
return this.mainHeight - this.seachPanelHeight
totalKeywordNodes () {
return this.keywordNodes.length
current () {
if (this.keywordNodes.length === 0) {
return 0
} else {
return this.activeNodeIndex + 1
onReady () {
this.getWindowHeight()
this.getFields()
this
.mockData()
methods: {
mockData () {
let temp = []
for (let i = 0; i < 4; i++) {
temp = temp.concat(this.newList)
this.setData({
newList: temp
getWindowHeight () {
const that = this
wx.getSystemInfo({
success (res) {
that.setData({
mainHeight: res.windowHeight
getFields () {
const that = this
const query = wx.createSelectorQuery()
query.select('#searchPanel').fields({
dataset: true,
size: true
}, res => {
that.setData({
seachPanelHeight: res.height
}).exec()
getInf (str, key) {
return str
.replace(new RegExp(`${key}`, 'g'), `%%${key}%%`)
.split('%%')
.filter(item => {
if (item) {
return true
return false
inpChange (e) {
let key = e.detail
this.setData({
activeNodeIndex: 0,
keywordNodes: [],
searchValue: e.detail
if (key) {
this.newList.forEach(element => {
if (element.jj instanceof Array) {
element.jj = element.jj.join('')
let newContent2 = this.getInf(element.jj, key)
element.jj = newContent2
this.$nextTick(() => {
wx.createSelectorQuery()
.selectAll('.searchHigh')
.boundingClientRect(res => {
let keywordNodes = res.map(item => item.id)
this.setData({
keywordNodes: keywordNodes
.select('.listPanel')
.node(res => {
this.setData({
scrollView: res.node
this.scrollToView(0)
.exec()
* @method 将节点滚动至可视窗口
* @param {number} index
scrollToView (index) {
this.$nextTick(() => {
this.scrollView.scrollIntoView("#" + this.keywordNodes[index])
* @method 控制上一条和下一条
* @param {string} type
handleScroll (type) {
switch (type) {
case 'pre':
if (this.activeNodeIndex === 0) {
this.activeNodeIndex = this.keywordNodes.length - 1
} else {
this.activeNodeIndex--
break;
default:
if (this.activeNodeIndex === this.keywordNodes.length - 1) {
this.activeNodeIndex = 0
} else {
this.activeNodeIndex++
break;
this.scrollToView(this.activeNodeIndex)
</script>
<style scoped>
.container {
width: 100%;
overflow: scroll;
--webkit-overflow-scrolling: touch-action;
.statistic-bar {
position: fixed;
left: 16px;
bottom: 30px;
right: 16px;
border-radius: 12rpx;
background-color: #e6f7ff;
z-index: 999;
display: flex;
justify-content: space-around;
width: calc(100% - 16px -16px);
padding: 16rpx 32rpx;
box-sizing: border-box;
font-size: 26rpx;
box-shadow: 6rpx 6rpx 15rpx rgba(0, 0, 0, 0.125), -6rpx 0rpx 15rpx rgba(0, 0, 0, 0.125);
color: #323233;
.listPanel {
box-sizing: border-box;
background-color: #f5f5f5;
.news_item {
width: 100%;
height: 208rpx;
padding: 0 32rpx;
margin: 32rpx 0;
box-sizing: border-box;
.descBox {
width: 100%;
height: 100%;
background: #fff;
border-radius: 12rpx;
padding: 24rpx;
box-sizing: border-box;
.news_title {
width: 100%;
font-size: 32rpx;
font-weight: 500;
text-align: left;
color: black;
margin-bottom: 10rpx;
.news_text {
font-size: 26rpx;
font-weight: 400;
color: #909090;
text-align: left;
margin-bottom: 7rpx;
display: -webkit-box;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
word-break: break-all;
.textoverflow {
display: -webkit-box;
-webkit-line-clamp: 1;
overflow: hidden;
text-overflow: ellipsis;
-webkit-box-orient: vertical;
word-break: break-all;
.searchHigh {
font-size: 36rpx;
color: #1d84f6;
font-weight: bold;
.selected {
background: #909090;
</style>
<script type="application/json">
"navigationBarTitleText": "搜索关键字高亮",
"usingComponents": {
"van-search": "@vant/weapp/dist/search/index"
</script>
原理把需要高亮的字段,分割成数组,用wx:for 在<text>中遍历数组,判断当前的item等不等于keyword等于就高亮。注意事项关键代码这里以item.title字段为例什么时候分割?进入列表页时是没有筛选的状态,当在搜索框输入时就可以进行分割了。就是不管你输入关键字还是删减关键字都要分割并且是关键字有值的时候分割该字段分割成数组了,当关键字改变时怎么办?这就有一个问题了,没输入关键字时,item.title是字符串,遍历字符串进行循环。当你输入关键
Sublime-wxapp
Sublime Text 3 syntax highlighting and auto completion for .wxml file(WeChat 'mini apps').
Install
Package Control
Search Sublime wxapp via Package Control: Install Package
Git clone this repository to Sublime Packages Path.
Download zip and unzip to Sublime Packages Path.
Setting
In order to improve WXML completion efficiency,you shuld edit your Preferences.sublime-settings
博主第一时间想到的就是使用split,根据搜索的关键词,处理后台返回的数据,然后indexOf找到关键字,给每个字添加deep字段,deep为true,则高亮,为false,则正常。由于是小程序,所以楼主直接做成了一个高亮组件,代码很简单,实现步骤如下。
3,代码逻辑
模拟数据如下
list:[
<view class="search-box">
<view class="input-box">
<image mode="widthFix" src="images/search.png"/>
<input class="searchInput"
微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞机大战(截图+源码)微信小程序 飞
很多项目中会有搜索,有时是要点击搜索按钮时搜索,有时是点击键盘完成搜索,还有时需要实时搜索,而高亮关键字也是一个常见的需求。
今天写一个实时搜索并高亮关键字的微信小程序demo,已上传GitHub,需要自取
微信小程序实时搜索高亮关键字demo
这是一个我项目中的截图,但是数据结构又略微有点复杂,不好演示,所以单独又写了一个demo,数据来自干活集中营
(此图片来源于网络,如有侵权,请联系删除! )
实时搜索高亮关键字
关键函数:将字符串使用关键字分割:
//返回一个使用key切割str后的数组,key仍在数组中
getHilightStrArray: function(str, ke
微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零食商城(截图+源码)微信小程序 零
xhtml
<view wx:for='{{searchsuggestions}}' wx:key='index'>
<rich-text nodes="{{item.keyword}}"></rich-text>
</view>
let data = res.result.allMatch//搜索到的数据
data.map((item) =>{
item.keyword = item.keyword.replace(t
<view class="search-box">
<view class="input-box">
<image mode="widthFix" src="../../assets/close.png" class="clearInput" bindtap="clearInput"/>
1. 在小程序的页面中添加一个搜索框组件,用户可以在该组件中输入关键字。
2. 使用input事件监听用户输入的关键字,在事件回调函数中获取用户输入的值。
3. 将获取到的关键字发送到后台服务器进行处理,可以使用小程序提供的wx.request方法发送HTTP请求。
4. 后台服务器根据关键字查询相关数据,并将查询结果返回给小程序。
5. 小程序接收到后台返回的数据后,将数据渲染到页面中展示给用户。
具体实现过程中,可以根据需求进行优化和增加一些功能,例如:
- 添加搜索历史记录功能,方便用户查看之前的搜索记录。
- 使用debounce或throttle函数控制搜索请求的频率,避免频繁发送请求。
- 使用分页加载等技术,提高搜索结果的展示效果和用户体验。
总之,关键字搜索功能的实现需要前后端协作,前端负责用户交互和展示,后端负责数据查询和处理。