实现效果如图:

主要代码:
<template v-slot:content>
<view class="cnt-pr" v-if="item.symbol"><rich-text class="rich-txt" :nodes="item.contentSel"></rich-text></view>
<view class="cnt-pr" v-else><text class="rich-txt">{{item.content}}</text></view>
</template>
inputChange(e) {
this.keywords = e.detail.value;
//关键词搜索
if(this.keywords){
var replaceString = '<span style="color:#f37b1d;font-size:16px;font-weight:bold;">' + this.keywords + "</span>";
this.dataList.map((item) => {
if(item.content.indexOf(this.keywords) > -1){
item.symbol = true;
item.contentSel = item.content.replaceAll(this.keywords, replaceString);
}else{
item.symbol = false;
item.contentSel = '';
}
});
}else{
this.clearInput();
}
},
实现代码:
<template>
<view>
<!-- 导航栏 -->
<cu-custom bgColor="bg-white" :isBack="true">
<block slot="content" color="#666666" v-if="!inputShowed">{{$t('cloudData.查询结果')}}</block>
<block slot="right">
<view class="s-bar" v-if="inputShowed">
<view class="l-pr">
<view class="ll-pr">
<uni-icons class="i-pr" type="search" color="#CCCCCC" size="18" />
<input confirm-type="search" class="s-bar-ipt" placeholder-class="s-bar-ipt-h" :placeholder="$t('common.请输入适配器编码/设备名称')" :value="keywords" :focus="inputShowed" @confirm="inputConfirm" @input="inputChange" />
</view>
<uni-icons class="i-pr" type="clear" color="#CCCCCC" size="16" v-if="keywords" @tap="clearInput" />
</view>
<view class="r-pr" @tap="hideInput">{{$t('common.取消')}}</view>
</view>
<view class="icon-pr" v-else>
<uni-icons class="ic-pr" type="search" color="#666666" size="20" @tap="showInput" />
</view>
</block>
</cu-custom>
<!--列表-->
<mescroll-body class="scrolly" ref="mescrollRef" :up="upOption" @init="mescrollInit" @down="downCallback">
<block v-for="(item, index) in dataList" :key="index">
<tui-collapse :index="index" :current="item.current" :disabled="item.disabled" @click="collapseChange">
<template v-slot:title>
<tui-list-cell class="tlt-pr" :hover="!item.disabled">
<text class="tlt-txt" :class="item.symbol?'bg-yellow':''">{{item.title}}</text>
</tui-list-cell>
</template>
<template v-slot:content>
<view class="cnt-pr" v-if="item.symbol"><rich-text class="rich-txt" :nodes="item.contentSel"></rich-text></view>
<view class="cnt-pr" v-else><text class="rich-txt">{{item.content}}</text></view>
</template>
</tui-collapse>
</block>
</mescroll-body>
</view>
</template>
<script>
import nText from "@/components/n-text/n-text.vue"
import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
export default {
mixins: [MescrollMixin], // 使用mixin
components: {
nText
},
data() {
return {
params: null,
keywords: '',
mescroll: null , //mescroll实例对象
inputShowed: false,
upOption: {
use: false, //关闭上拉加载
},
//所有数据集
dataList: [],
}
},
onLoad(option) {
console.log(option.param)
this.params = option.param;
},
methods: {
//搜索框功能函数
showInput() {
this.inputShowed = true;
},
hideInput() {
this.inputShowed = false;
uni.hideKeyboard(); //强行隐藏键盘
//清除标记
this.clearInput();
},
clearInput() {
this.keywords = "";
for (var i = 0; i < this.dataList.length; i++) {
this.dataList[i].symbol = false;
this.dataList[i].contentSel = '';
}
},
inputChange(e) {
this.keywords = e.detail.value;
//关键词搜索
if(this.keywords){
var replaceString = '<span style="color:#f37b1d;font-size:16px;font-weight:bold;">' + this.keywords + "</span>";
this.dataList.map((item) => {
if(item.content.indexOf(this.keywords) > -1){
item.symbol = true;
item.contentSel = item.content.replaceAll(this.keywords, replaceString);
}else{
item.symbol = false;
item.contentSel = '';
}
});
}else{
this.clearInput();
}
},
inputConfirm(e) {
this.keywords = e.detail.value;
},
//可展开列表
collapseChange(e) {
let index = e.index;
let item = this.dataList[index];
item.current = item.current == index ? -1 : index;
},
//下拉刷新
downCallback(){
let params = {
cmuid: uni.getStorageSync('cmuid'),
adaptorCode: 'F06215068025'//this.params.adapterCode
}
this.api.getOperateRecord(params).then(res => {
console.log(res)
if (res.data && res.data.msgCode && res.data.msgCode == "0") {
//联网成功的回调,隐藏下拉刷新的状态
this.mescroll.endSuccess();
//处理数据
var datas = res.data.data;
//构建数据集
this.dataList = [];
for (var i = 0; i < datas.length; i++) {
var item = {};
item.title = (i+1) +". "+ datas[i].timestamp;
item.content = JSON.stringify(datas[i]);
item.current = -1;
item.disabled = false;
item.symbol = false;
item.contentSel = '';
this.dataList.push(item);
}
} else {
this.mescroll.endErr();
this.api.showComToast(res.message);
}
}).catch(error => {
//联网失败的回调,隐藏下拉刷新的状态
this.mescroll.endErr();
})
},
}
}
</script>
<style lang="scss">
.s-bar{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 3rpx 3rpx 3rpx 10rpx;
.l-pr{
width: 85%;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: 30rpx;
background-color: #f2f2f2;
.ll-pr{
flex: 1;
display: flex;
flex-wrap: wrap;
align-items: center;
.s-bar-ipt{
flex: 1;
font-size: 26rpx;
color: black;
}
.s-bar-ipt-h{
flex: 1;
color: #CCCCCC;
font-size: 26rpx;
}
}
.i-pr{
margin: 10rpx;
}
}
.r-pr{
width: 14%;
font-size: 24rpx;
text-align: center;
padding-right: 5rpx;
}
}
.icon-pr{
width: 100%;
display: flex;
flex-wrap: wrap;
flex-direction: row-reverse;
.ic-pr{
margin-right: 25rpx;
}
}
.scrolly{
.tlt-pr{
margin-top: 10rpx;
font-weight: bold;
.tlt-txt{
font-size: 32rpx;
}
}
.cnt-pr{
padding: 10rpx 15rpx;
font-size: 24rpx;
.rich-txt{
word-break: break-all;
white-space: pre-line;
}
}
}
</style>