v-html在微信小程序中不生效是因为被编译为rich-text组件,仅支持text节点和class样式;正确做法是用转义后的正则匹配关键词,生成含highlight class的nodes数组渲染。

微信小程序里 uni-app 搜索关键词高亮为什么 v-html 不生效
因为微信小程序的 v-html 实际上被编译成 rich-text 组件,而该组件不支持嵌套 text 标签以外的节点,也不支持内联样式(比如 color: red)。直接用正则替换加 span 标签再塞进 v-html,结果是空白或原样输出。
正确做法是:用正则提取匹配段落,生成带 class 的文本数组,再用 rich-text 的 nodes 属性渲染。
- 必须把高亮文本拆成纯文本节点 + 带 class 的
text节点,不能混用 HTML 字符串 -
nodes数组中每个元素类型为{ name: 'text', attrs: { class: 'highlight' }, children: [...] }或纯字符串 - 正则需使用
g和i标志,且要处理空关键词、特殊字符转义(如searchKey.replace(/[.*+?^${}()|[]\]/g, '\$&'))
如何用 RegExp 安全匹配并分割搜索词
关键词可能含正则元字符(如 +、(、[),不转义会导致 RegExp 构造失败或误匹配。也不能直接用 new RegExp(searchKey, 'gi')。
实操建议:
- 先对
searchKey做字符转义:const escaped = searchKey.replace(/[.*+?^${}()|[]\]/g, '\$&') - 再构造正则:
const reg = new RegExp(escaped, 'gi') - 用
str.split(reg)得到非匹配片段,用str.match(reg)得到匹配项;注意两者长度差 1,需交替拼接 - 更稳妥用
str.replace配合回调,但回调中不能直接返回 HTML 字符串——要返回nodes结构
rich-text 的 nodes 数组怎么组织高亮节点
微信小程序 rich-text 的 nodes 是个数组,每个元素可以是字符串(普通文本)或对象(节点)。高亮部分必须用对象,且只支持 name: 'text',attrs 里只能写 class(不能写 style),children 必须是字符串数组(哪怕只有一个)。
示例代码片段:
<rich-text :nodes="highlightNodes(item.title, searchKey)"></rich-text>
- 小程序:走
rich-text + nodes方案 - H5:可用
v-html+ 正则替换xxx - App:推荐用
web-view或原生渲染插件,避免v-html安全风险
最易忽略的是:开发时只测 H5,上线小程序才发现高亮全失效——因为没走 nodes 分支,也没加条件编译判断平台。











