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,微信小程序段落换行正常;百度小程序:

  1. 多个连续 <p>,段落合并,丢失换行;
  2. 部分段落直接消失;
  3. 文本堆叠在一起,排版完全错乱。

根因

百度小程序底层解析引擎对 <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)

  1. content 必须保证字符串类型,接口返回null/undefined要兜底为空字符串,不能直接传非字符串;
this.rawHtml = res.content || ''
  1. 编译问题:修改代码后,清除百度小程序开发者工具缓存,重新执行 yarn dev:mp‑baidu
  2. 不要依赖富文本内 class 类样式;百度小程序富文本内 class 经常失效,优先使用行内 style 样式
  3. tag‑style只接收标签名:css字符串,禁止true / false / number
  4. 条件渲染,增加v‑if="fixedHtml",防止 content 为空时组件做异常解析。

总结

  1. split is not a functiontag‑style传了布尔值,value 必须是 css 字符串,不要当开关使用
  2. 百度小程序 <p> 标签渲染错乱 → 预处理替换为带样式 div,微信端不受影响,可以全端通用该预处理函数
  3. 富文本优先行内 style,减少 class,避免跨平台样式不一致。


原创文章,作者:ECHO陈文,如若转载,请注明出处:https://www.luweipai.cn/uniapp/1788793233/

  • 1