uni‑app 百度小程序 mp‑html 两大深坑:p 标签渲染失效 + tag‑style split is not a function
`mp‑html` 在微信小程序表现稳定,但迁移百度小程序会踩两个典型坑:`<p>` 段落标签渲染错乱空白;错误使用 `tag‑style` 抛出 `split is not a function`,本文完整记录复现、根因、完整可运行代码与避坑总结。
问题背景
uni‑app 项目,后端返回标准 HTML 富文本,大量使用 <p> 标签做段落分隔。
微信小程序端一切正常;百度小程序端出现异常:段落丢失、文本堆在一起,甚至页面直接报错白屏。
报错堆栈:
TypeError: (this.tagStyle[node.name] || "").split is not a function
原始后端返回 HTML 示例:
<p>装修监理主要负责装修哪方面</p>
<p>1、帮忙审核报价预算,确保无坑,不漏项,无恶意增项;</p>
<p>2、检查所需装修的材料的品牌和等级以及全部清单;</p>
<p>3、对进场材料进行验收,检查进场材料是否存在瑕疵或者劣质;装修监理主要负责装修的哪方面</p>
<p>4、对施工各个环节进行把关,检查,确保施工质量符合国家标准,未达标施工,协助业主与施工方沟通并做整改;</p>
坑一:tag‑style 报 split is not a function
错误写法(网上部分错误示例会误导)
<!-- ❌错误:tag‑style 中不要写 true/false布尔值 -->
<mp-html :content="htmlStr" :tag-style="{ div: true }" />
根因分析
tag‑style 的设计:key 是 HTML 标签名,value 必须是 CSS 字符串,不是布尔开关GitHub。
组件内部源码会执行类似逻辑:
(this.tagStyle[node.name] || "").split(';')
如果你传入 div:true,值是布尔,布尔类型没有 .split() 方法,直接抛出类型错误,页面白屏崩溃。
很多人误以为 tag‑style 是 “开启该标签” 的开关,这是完全错误理解。它的作用:给对应标签注入默认内联 CSS 样式。
✅ 正确用法:
<!-- 给div设置默认样式,值是css字符串 -->
<mp-html
:content="htmlStr"
:tag-style="{ div: 'margin-bottom:12rpx;line-height:1.7' }"
/>
<!-- 不需要全局标签样式,直接删掉 tag‑style 属性即可 -->
<mp-html :content="htmlStr" />
坑二:百度小程序 <p> 标签渲染异常(微信正常,百度乱)
现象
同样一份 HTML,微信小程序段落换行正常;百度小程序:
- 多个连续
<p>,段落合并,丢失换行; - 部分段落直接消失;
- 文本堆叠在一起,排版完全错乱。
根因
百度小程序底层解析引擎对 <p> 标签兼容性缺陷,即使 mp‑html 组件做了兼容,实际业务中依然频繁踩坑。百度小程序建议尽量规避大量<p>标签,优先使用<div>实现段落。
解决方案:JS 预处理 HTML 字符串
把所有<p>替换为带段落边距的<div>,同时清除 HTML 内部换行符\n \r(百度小程序解析器容易被隐形换行干扰)。
完整预处理工具函数:
/**
* 百度小程序富文本兼容处理
* 将p标签转为div,清除换行符,规避百度小程序p标签渲染bug
* @param {String} htmlStr 原始富文本
* @returns {String} 处理后html
*/
export function fixBaiduRichHtml(htmlStr) {
if (!htmlStr) return ''
let result = htmlStr
// p标签替换为带段落样式div
result = result.replace(/<p>/g, '<div style="margin-bottom:12rpx;line-height:1.7;">')
result = result.replace(/<\/p>/g, '</div>')
// 删除换行回车隐形字符
result = result.replace(/[\n\r]/g, '')
return result
}
Vue 页面完整使用示例
<template>
<view class="article">
<!-- v‑if:等待html不为空再渲染,避免空内容解析异常 -->
<mp-html v-if="fixedHtml" :content="fixedHtml" :selectable="false" />
</view>
</template>
<script>
import { fixBaiduRichHtml } from '@/utils/html‑fix.js'
export default {
data() {
return {
rawHtml: '',
fixedHtml: ''
}
},
onLoad() {
// 模拟接口请求
this.getArticle()
},
methods: {
async getArticle() {
// 接口拿到原始富文本
const res = await api.getContent()
this.rawHtml = res.content || ''
// 做兼容预处理
this.fixedHtml = fixBaiduRichHtml(this.rawHtml)
}
}
}
</script>
其他配套避坑清单(百度小程序 mp‑html)
- content 必须保证字符串类型,接口返回
null/undefined要兜底为空字符串,不能直接传非字符串;
this.rawHtml = res.content || ''
- 编译问题:修改代码后,清除百度小程序开发者工具缓存,重新执行
yarn dev:mp‑baidu; - 不要依赖富文本内 class 类样式;百度小程序富文本内 class 经常失效,优先使用行内 style 样式;
tag‑style只接收标签名:css字符串,禁止true / false / number;- 条件渲染,增加
v‑if="fixedHtml",防止 content 为空时组件做异常解析。
总结
split is not a function→tag‑style传了布尔值,value 必须是 css 字符串,不要当开关使用;- 百度小程序
<p>标签渲染错乱 → 预处理替换为带样式 div,微信端不受影响,可以全端通用该预处理函数; - 富文本优先行内 style,减少 class,避免跨平台样式不一致。
原创文章,作者:ECHO陈文,如若转载,请注明出处:https://www.luweipai.cn/uniapp/1788793233/