mp-html是解决小程序rich-text样式与交互限制的终极方案,支持50+html标签、图片预览、链接跳转、长按复制及灵活样式控制,兼容微信、qq、支付宝等全平台。

小程序端的 rich-text 组件不支持运行时动态修改样式,这是底层限制,不是写法问题。 你不能靠绑定 v-bind:style、切换 class 或用 JS 操作 DOM 来实时改已渲染内容的样式——它压根不暴露 DOM 节点,也不响应 style 属性变更。
rich-text 的 nodes 属性必须一次性传入完整节点结构
很多人误以为 nodes 是响应式“容器”,可以 push 新节点或修改已有节点的 attrs.style。实际上:一旦组件挂载,nodes 数组哪怕 shallow change(比如改了某个节点的 attrs),rich-text 也不会重绘该节点的样式。
- 必须重新赋值整个
nodes数组(哪怕只改一个img的style) - 节点对象是不可变的:不能直接
nodes[0].attrs.style = '...',要深拷贝后替换 - 若用正则处理 HTML 字符串再 parse 成 nodes,每次改动都得走一遍解析流程(推荐用
DOMParser,别手写正则匹配嵌套标签)
小程序平台下 class 样式基本无效,只认内联 style
即使你在 nodes 里写了 class: "my-img",并在页面 <style></style> 中定义了 .my-img { border-radius: 8px; },小程序端也大概率不生效。原因有二:
- 小程序
rich-text不支持 class 选择器,只解析style属性 - 即使加了
styleIsolation: "shared"或::v-deep,也无法穿透到rich-text内部生成的<image></image>组件上(它不是普通 view)
所以所有样式必须塞进 attrs.style 字符串里,例如:{ name: 'img', attrs: { src: '...', style: 'max-width:100%; border-radius:6px;' }, children: [] }。
想动态改图/段落样式?得提前约定好数据结构
如果你的需求是“用户点击按钮,把当前富文本里所有图片加圆角”或“切换深色模式时统一调亮文字颜色”,靠临时 patch HTML 不现实。正确做法是:
- 服务端返回的原始 HTML 里不要带
style,只保留语义标签(<p></p>、<img>等) - 前端统一用函数处理:根据当前主题、屏幕宽度、用户偏好等条件,动态生成带完整
style的nodes数组 - 把样式逻辑抽成纯函数,例如
buildNodes(html, { theme: 'dark', maxWidth: '100%' }),便于测试和复用
这样每次状态变化,只需触发一次 nodes = buildNodes(...),避免零散 patch 和样式残留。
mp-html 是更可控的替代方案,但仍有边界
如果业务中频繁需要动态样式控制(比如编辑器预览、主题切换、A/B 测试),rich-text 就太僵硬了。这时 mp-html 更合适,因为它:
- 支持
tag-style配置项,可统一设置img、p等标签默认样式 - 允许通过
config动态传入样式规则,且会实时响应 - 提供
@error、@load等事件,方便做图片懒加载或 fallback
但注意:mp-html 本身不支持“编辑”,它仍是只读渲染;且其 tag-style 是静态配置,若需 per-node 动态 style(如某张图单独设高度),仍得预处理 HTML 字符串或改写其 parser 规则。
真正麻烦的地方不在怎么写代码,而在于:你得先明确哪些样式是“全局策略”(可配)、哪些是“单节点定制”(需预处理)、哪些根本没法做(比如给某个 span 加 hover 效果——小程序没 hover)。没想清楚这三层,后面全是补丁。











