v-html 不支持过滤器,因其绑定的是原始 HTML 字符串,不经过 Vue 表达式编译器解析,管道符无法执行;正确做法是在 JS 层处理字符串(如正则高亮)后传入 v-html,或改用 rich-text 组件。

v-html 里不能用过滤器,语法上就不支持,写了也白写。 因为 v-html 绑定的是原始 HTML 字符串,Vue 模板编译器不会对它做任何表达式解析,| 管道符根本进不去执行流程。
为什么 {{ value | filter }} 能用,v-html 就不行
v-html 的值必须是纯字符串(如 '<span class="red">hello</span>'),它不经过 Vue 的表达式编译器,所以里面写 {{ item.text | upper }} 会被当作文本原样输出,不会执行过滤逻辑。常见错误写法:
-
v-html="{{ content | highlight }}"→ 编译报错:Invalid expression -
v-html="content | highlight"→ 运行时highlight未定义(因为没注册,或注册了但v-html不走过滤器链)
想在 v-html 里“高亮关键词”,得先处理好字符串再塞进去
过滤器的职责是转换值,不是拼 HTML;v-html 的输入必须是合法、安全的 HTML 字符串。所以正确路径是:在 JS 层完成替换,再把结果交给 v-html。
- 别在模板里调过滤器,改在
data、computed或methods中处理:this.highlightedHtml = this.content.replace(new RegExp(this.keyword, 'g'), `<font color="#DF2D45">${this.keyword}</font>`) - 关键词必须正则转义,否则用户输
+或[会崩:keyword.replace(/[.*+?^${}()|[]\]/g, '\$&') - 小程序只认
<font></font>标签,<span style="color:red"></span>会被过滤掉,别用 - H5 端可用
<mark></mark>或<strong></strong>,但跨端必须统一用<font></font>才能保底
更稳妥的替代方案:rich-text + nodes 数组
v-html 在小程序平台有严重限制(标签被剥离、样式失效),真要全端一致,应弃用 v-html,改用 rich-text 组件 + 动态生成 nodes。
立即学习“前端免费学习笔记(深入)”;
-
rich-text接收结构化数据,天然规避 XSS 风险,且<font></font>渲染稳定 - 用
text.matchAll(regex)定位关键词位置,逐段生成{ name: 'text', children: [...] }和{ name: 'font', attrs: { color: '#' }, children: [...] } - 注意:不能直接对整个 HTML 字符串做
replace,富文本里可能含<img>或<br>,需先解析再高亮,否则破坏标签结构
最易被忽略的一点:你写的过滤器函数,哪怕注册成功、在 {{ }} 里跑得通,只要进了 v-html 的作用域,就彻底失效——这不是 bug,是设计使然。别试图绕过,老老实实把 HTML 拼好再交出去。


















