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 必须是字符串数组(哪怕只有一个)。
示例代码片段:
const highlightNodes = (text, key) => {
if (!key || !key.trim()) return [{ name: 'text', children: [{ text }] }];
const escaped = key.replace(/[.*+?^${}()|[]\]/g, '\$&');
const reg = new RegExp(escaped, 'gi');
const parts = [];
let lastIndex = 0;
text.replace(reg, (match, offset) => {
if (offset > lastIndex) {
parts.push({ name: 'text', children: [{ text: text.slice(lastIndex, offset) }] });
}
parts.push({
name: 'text',
attrs: { class: 'highlight' },
children: [{ text: match }]
});
lastIndex = offset + match.length;
});
if (lastIndex < text.length) {
parts.push({ name: 'text', children: [{ text: text.slice(lastIndex) }] });
}
return parts;
};
模板中绑定:<rich-text :nodes="highlightNodes(item.title, searchKey)"></rich-text>,再配 CSS:.highlight { color: #07c160; font-weight: 500; }
为什么在 H5 或 App 端能用 v-html,但小程序不行
uni-app 编译目标不同:v-html 在 H5 下渲染为真实 HTML,在小程序下被强制降级为 rich-text,而微信的 rich-text 对节点结构极其严格——不允许 span、不认 style、不支持事件绑定。这不是 uni-app 的 bug,是平台限制。
所以跨端统一方案不存在。必须条件编译:
- 小程序:走
rich-text + nodes方案 - H5:可用
v-html+ 正则替换<span class="highlight">xxx</span> - App:推荐用
web-view或原生渲染插件,避免v-html安全风险
最易忽略的是:开发时只测 H5,上线小程序才发现高亮全失效——因为没走 nodes 分支,也没加条件编译判断平台。



















