v-html仅将字符串赋给innerhtml,不解析vue语法、不响应数据变化、不可与v-model等共用、禁用于组件根元素、ssr时不水合,且直接渲染不可信html会导致xss,须用dompurify净化或改用markdown/ast等安全方案。

v-html 是 Vue 3 中唯一能直接把字符串当 HTML 解析并插入 innerHTML 的指令,但它本身不做任何过滤、转义或校验——传什么,浏览器就执行什么。所以“怎么用”不难,“怎么用得安全”才是关键。
明确 v-html 的边界和限制
它只做一件事:把绑定的字符串赋给元素的 innerHTML。这意味着:
- 不会解析 {{ }}、v-if、组件标签等 Vue 语法
- 不响应数据变化——改了原始值,DOM 不自动更新,必须重新赋值
- 不能和 v-model、v-if、v-for 等指令写在同一元素上
- 不能用于组件的根元素(会报错)
- 服务端渲染(SSR)时,内容不会被水合接管,易导致 DOM 不一致
绝不直接渲染不可信来源的内容
用户评论、富文本编辑器输出、CMS 后台导出的 HTML,表面是排版,实则可能藏有:
<script>alert('xss')</script><img src="x" onerror="fetch('/steal?c='+document.cookie)">@#@#@#@#@#@#@#@#@#@0
Vue 不拦截、不沙箱、不警告。一旦插入,这些代码就会真实执行。
必须搭配 HTML 净化方案
前端可用 DOMPurify 做轻量级净化,但仅作辅助,不能替代后端清洗:
- 安装:
npm install dompurify - 在
setup或computed中处理:
const safeHtml = computed(() => DOMPurify.sanitize(rawHtml, {
ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'a', 'ul', 'ol', 'li'],
ALLOWED_ATTR: ['href', 'title']
})) - 模板中绑定:
<div v-html="safeHtml"></div>
更推荐的长期方案:绕开 v-html
多数业务其实不需要完整 HTML 支持,可转向更可控的方式:
- 纯文本+简单格式:用正则转义(如
**bold** → <strong>bold</strong>),再配合v-html限定白名单 - 结构化富文本:后端返回 Markdown 或自定义 JSON AST(如
{ type: 'bold', children: ['文本'] }),前端用递归组件渲染 - 完全规避:用
{{ }}显示纯文本,或用v-text防止意外解析
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











