uni-app中不能用过滤器实现关键词高亮,因vue2不支持v-html链式调用带参过滤器,vue3已移除过滤器;必须用computed或methods配合正则预处理,且需转义关键词特殊字符、生成rich-text nodes数组以全端兼容。

uni-app 里不能用 Vue 过滤器做关键词高亮
直接写 v-html="content | highlight(keyword)" 会失败——uni-app 的 Vue2 模式不支持在 v-html 中链式调用带参数的过滤器;Vue3 的 Composition API 更不支持过滤器。这不是写法问题,是机制限制。
真正能落地的方式只有两种:计算属性(computed)或方法(methods),且必须配合正则预处理。所有“过滤器高亮”的尝试,最终都得退回到字符串替换逻辑。
高亮前必须 escape 关键词里的正则特殊字符
用户搜 vue+cli 或 file.txt,不转义就会触发正则语法错误或漏匹配。比如 . 被当通配符、+ 要求前字符重复,结果整个 replace 报错或返回空。
- 必须用这个转义函数:
keyword.replace(/[.*+?^${}()|[]]/g, '\$&') - 注意:方括号
[和]在正则里要成对出现,但这里只是字面量转义,所以只对单个[转义即可(知识库已验证) - 别用第三方库如
escape-string-regexp—— uni-app 小程序端不支持动态require,打包会丢掉
replace 必须用 new RegExp(escaped, 'gi'),不能用字符串参数
text.replace(keyword, '<span class="hl">$&</span>') 只换第一个;text.replaceAll(keyword, ...) 在 iOS 旧 WebView 和部分安卓机上直接报错或静默失效。
- 正确写法:
const regex = new RegExp(escapedKeyword, 'gi');然后text.replace(regex, '<span class="hl">$&</span>') -
$&是关键——它原样保留匹配内容(含大小写),比$1安全,也不用提前加括号 - 别在
data里存替换后的 HTML 字符串,要在computed里实时生成并decodeURIComponent解码(防v-html自动转义)
小程序平台必须用 rich-text + nodes 数组,v-html 无效
H5 上 v-html 能渲染 <span></span>,但微信/支付宝/百度小程序会直接过滤掉非白名单标签,只剩纯文本。现象是:安卓真机看着好好的,iOS 或小程序开发者工具里高亮全消失。
- 唯一全端兼容方案:用
matchAll()找出所有匹配位置,拼nodes数组,每个匹配项包一层{ name: 'font', attrs: { color: '#f00' }, children: [...] } -
rich-text不支持style或class,颜色只能靠<font color="#f00"></font>,粗体得用font-weight外层样式兜底 - 空关键词守卫必须写在
nodes生成函数最开头:if (!keyword || keyword.trim() === '') return [{ name: 'text', children: [{ text }] }];
watch 只监听了 keyword,没监听 list 或响应式数据源,导致旧内容一直挂着过期的高亮。










