ios和小程序中rich-text高亮无颜色,因不支持style属性及span标签,仅识别font节点;须用name为"font"、attrs含color的nodes数组,关键词需正则转义,replace必须加g标志,空关键词要守卫,ios颜色失效常因rpx缩放或scoped样式导致。

uni-app里用rich-text渲染高亮,为什么iOS和小程序没颜色?
因为rich-text不支持style属性或span标签,只认font标签和基础文本节点。直接塞<span style="color:red">关键词</span>在小程序或iOS上会被过滤成纯文本,或者样式失效。
正确做法是生成符合rich-text规范的nodes数组,每个匹配项用font节点包裹:
-
name必须是"font",不能是"span"或"div" -
attrs里写{ color: "#e74c3c" },不是style - 非匹配文本用
{ name: "text", children: [{ text: "xxx" }] } - 关键词本身要先用
escapeRegExp()转义,否则输入+、[会报错
正则替换时只高亮第一个词,replace漏了哪个标志?
缺g(global)标志。写成new RegExp(keyword, "i")或new RegExp(keyword, "gi")但没加g,就只替换首次匹配——这是真机调试时最常看到“只红一个词”的原因。
还要注意:i(ignoreCase)得带上,否则“Vue”搜不出“vue”;但keyword含.、*等特殊字符时,必须先转义,否则new RegExp(keyword, "gi")直接抛错:
- 转义函数:
escapeRegExp(str) { return str.replace(/[.*+?^${}()|[]\]/g, "\$&"); } - 构造正则:
const reg = new RegExp(`(${escapedKeyword})`, "gi") - 替换用
$&,不是$1,避免空捕获组出错
用户清空搜索框后,整个列表变红一片,守卫逻辑怎么写?
空字符串""或null传给正则,new RegExp("", "gi")会匹配任意位置,导致每个字符都被套进font,全屏变色。
守卫必须严格且前置:
- 用
if (!keyword || keyword.trim() === "") return text - 别用
== null,"" == null为false,守不住 -
trim()防用户输空格后触发误匹配 - 这个判断要放在所有正则操作之前,哪怕只是
data里默认值也要检查
安卓正常、iOS文字没变色,是不是rpx惹的祸?
极大概率是。iOS下v-html或rich-text内联颜色容易被父级font-size: 28rpx等缩放影响,导致color被继承覆盖或解析异常。
临时解法:
- 把
color提到外层class里定义,不要写在font的attrs中 - 或改用十六进制全写:
color: "#e74c3c",别用red、rgb() - 检查是否用了
scoped样式,rich-text内部节点不受作用域影响,需全局样式或deep穿透
真正稳定的做法:放弃v-html,全程走rich-text + nodes数组,再配全局.highlight { color: #e74c3c; }类,绕开平台对内联样式的解析差异。











