uni-app 微信小程序富文本展示样式优化指南:打造优雅的阅读体验

uni-app 小程序富文本展示样式优化指南:打造优雅的阅读体验

前言

在小程序开发中,富文本内容的展示是一个常见但又容易被忽视的场景。无论是新闻资讯、产品详情还是技术文档,富文本的渲染质量直接影响用户的阅读体验。

原生 rich-text 组件虽然简单易用,但样式可控性差,难以实现精致的排版效果。本文将从方案选型、样式优化、性能调优等多个维度,系统性地讲解如何在 uni-app 小程序中打造优雅的富文本展示效果。


一、富文本方案选型对比

在开始优化之前,我们需要选择合适的富文本解析方案。目前 uni-app 生态中主流的方案有以下几种:

方案 优点 缺点 适用场景
rich-text(原生) 性能最好、官方支持、无需额外依赖 样式可控性极差、不支持图片预览、标签支持有限 简单文本展示、对样式要求不高
mp-html 功能最全、支持多平台、样式灵活、支持图片预览和懒加载 体积稍大、配置略复杂 复杂富文本、需要高度自定义样式
u-parse uView 生态集成、API 简洁 功能相对基础、维护活跃度一般 uView 项目、中等复杂度
wxParse 老牌方案、文档丰富 年久失修、兼容性问题多 老项目维护

结论:90% 的场景推荐使用 mp-html,它是目前功能最完善、维护最活跃的小程序富文本组件,也是本文重点讲解的方案。


二、mp-html 快速上手

2.1 安装方式

方式一:插件市场导入(推荐)

直接在 DCloud 插件市场 搜索 mp-html,点击「使用 HBuilderX 导入插件」即可。

方式二:npm 安装

bash 复制代码
npm install mp-html

方式三:源码集成

将下载的源码中 dist/uni-app 目录下的文件拷贝到项目的 components/mp-html 目录。

2.2 基础配置

pages.json 中配置 easycom 自动引入:

json 复制代码
{
  "easycom": {
    "autoscan": true,
    "custom": {
      "^mp-html(.*)": "@/components/mp-html/mp-html.vue"
    }
  }
}

2.3 基础使用

vue 复制代码
<template>
  <view class="article-container">
    <mp-html
      :content="htmlContent"
      :tag-style="tagStyle"
      @imgtap="onImageTap"
    />
  </view>
</template>

<script>
export default {
  data() {
    return {
      htmlContent: '<h1>标题</h1><p>这是一段富文本内容...</p>',
      tagStyle: {
        // 标签样式配置,后面详细讲解
      }
    }
  },
  methods: {
    onImageTap(e) {
      // 图片点击预览
      uni.previewImage({
        current: e.detail.src,
        urls: e.detail.imgs
      })
    }
  }
}
</script>

三、核心样式优化技巧

3.1 全局排版基础

好的排版从基础参数开始。以下是经过大量实践验证的「黄金排版参数」:

javascript 复制代码
const tagStyle = {
  // 全局容器
  body: 'font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif; font-size: 30rpx; line-height: 1.8; color: #333;',
  
  // 段落
  p: 'margin: 24rpx 0; text-align: justify; letter-spacing: 1rpx;',
  
  // 标题层级
  h1: 'font-size: 44rpx; font-weight: 600; margin: 48rpx 0 24rpx; line-height: 1.4; color: #1a1a1a;',
  h2: 'font-size: 38rpx; font-weight: 600; margin: 40rpx 0 20rpx; line-height: 1.4; color: #1a1a1a;',
  h3: 'font-size: 34rpx; font-weight: 600; margin: 32rpx 0 16rpx; line-height: 1.5; color: #222;',
  h4: 'font-size: 32rpx; font-weight: 600; margin: 28rpx 0 14rpx; line-height: 1.5; color: #222;',
  h5: 'font-size: 30rpx; font-weight: 600; margin: 24rpx 0 12rpx; line-height: 1.6; color: #333;',
  h6: 'font-size: 28rpx; font-weight: 600; margin: 20rpx 0 10rpx; line-height: 1.6; color: #444;'
}

排版参数说明:

  • 行高 1.8:移动端阅读的最佳行高,既不拥挤也不松散
  • 字间距 1rpx:轻微拉开字间距,大幅提升可读性
  • 两端对齐text-align: justify 让右侧边缘整齐,视觉更舒适
  • 字号梯度:标题字号按 44→38→34→32→30→28 递减,层级清晰

3.2 图片优化

图片是富文本中最容易出问题的元素,常见问题包括:超出屏幕宽度、加载闪烁、布局偏移。

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  // 图片自适应
  img: 'max-width: 100%; height: auto; display: block; margin: 24rpx auto; border-radius: 12rpx; box-sizing: border-box;',
  
  // 图片说明文字
  figcaption: 'font-size: 26rpx; color: #999; text-align: center; margin: 12rpx 0 24rpx; line-height: 1.5;'
}

进阶优化:图片懒加载与占位图

vue 复制代码
<mp-html
  :content="htmlContent"
  :tag-style="tagStyle"
  :lazy-load="true"
  :img-mode="'widthFix'"
  placeholder="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 400 300'%3E%3Crect fill='%23f5f5f5' width='400' height='300'/%3E%3C/svg%3E"
/>

图片优化要点:

  1. max-width: 100% 确保图片不超出容器
  2. border-radius: 12rpx 圆角让图片更柔和
  3. 懒加载减少首屏加载时间
  4. 占位图避免布局抖动(CLS)

3.3 引用块美化

引用块(blockquote)是文章中常见的元素,好的引用样式能让内容层次分明。

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  blockquote: 'margin: 32rpx 0; padding: 24rpx 28rpx; background: linear-gradient(135deg, #f8f9fa 0%, #f1f3f5 100%); border-left: 8rpx solid #4a90e2; border-radius: 0 12rpx 12rpx 0; color: #555; font-size: 28rpx; line-height: 1.7;',
  
  // 引用内的段落重置边距
  'blockquote p': 'margin: 12rpx 0;'
}

设计思路:

  • 左侧彩色竖条 + 浅灰渐变背景,视觉上有层次感
  • 圆角只保留右侧,与左侧竖条形成对比
  • 字号略小于正文,暗示「次要内容」

3.4 代码块美化

对于技术类文章,代码块的展示至关重要。

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  // 行内代码
  code: 'background: #f6f8fa; padding: 4rpx 12rpx; border-radius: 8rpx; font-family: "SF Mono", Monaco, "Courier New", monospace; font-size: 26rpx; color: #e36209;',
  
  // 代码块
  pre: 'background: #282c34; color: #abb2bf; padding: 28rpx; border-radius: 12rpx; overflow-x: auto; margin: 24rpx 0; font-size: 26rpx; line-height: 1.6;',
  
  'pre code': 'background: transparent; padding: 0; color: inherit; font-size: inherit;'
}

代码块优化建议:

  • 深色背景 + 语法高亮,符合开发者阅读习惯
  • 横向滚动避免代码折行
  • 使用等宽字体保证对齐

💡 提示 :mp-html 支持通过扩展实现代码高亮,可引入 highlight.js 扩展获得更专业的代码着色效果。

3.5 表格样式优化

表格在小程序中容易出现宽度溢出问题,需要特殊处理。

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  // 表格容器
  table: 'width: 100%; border-collapse: collapse; margin: 24rpx 0; font-size: 26rpx;',
  
  // 表头
  th: 'background: #f6f8fa; font-weight: 600; text-align: left; padding: 16rpx 20rpx; border: 1rpx solid #e5e7eb; color: #374151;',
  
  // 单元格
  td: 'padding: 16rpx 20rpx; border: 1rpx solid #e5e7eb; color: #4b5563;',
  
  // 斑马纹(偶数行)
  'tr:nth-child(even)': 'background: #fafbfc;'
}

表格优化要点:

  1. 表头背景色区分层级
  2. 斑马纹提升多行可读性
  3. 适当的内边距避免内容拥挤

3.6 列表样式优化

有序列表和无序列表的缩进和间距需要精细调整。

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  // 无序列表
  ul: 'margin: 20rpx 0; padding-left: 48rpx;',
  'ul li': 'margin: 12rpx 0; line-height: 1.7; list-style-type: disc;',
  
  // 有序列表
  ol: 'margin: 20rpx 0; padding-left: 48rpx;',
  'ol li': 'margin: 12rpx 0; line-height: 1.7; list-style-type: decimal;',
  
  // 嵌套列表
  'ul ul, ol ul, ul ol, ol ol': 'margin: 8rpx 0; padding-left: 36rpx;'
}

3.7 分割线与强调元素

javascript 复制代码
const tagStyle = {
  // ... 其他样式
  
  // 分割线
  hr: 'border: none; height: 2rpx; background: linear-gradient(90deg, transparent, #e5e7eb, transparent); margin: 40rpx 0;',
  
  // 加粗
  strong: 'font-weight: 600; color: #1a1a1a;',
  b: 'font-weight: 600; color: #1a1a1a;',
  
  // 斜体
  em: 'font-style: italic; color: #555;',
  
  // 删除线
  del: 'text-decoration: line-through; color: #999;',
  
  // 链接
  a: 'color: #4a90e2; text-decoration: none; border-bottom: 1rpx solid rgba(74, 144, 226, 0.3);',
  
  // 标记文本
  mark: 'background: #fff3cd; padding: 2rpx 8rpx; border-radius: 6rpx; color: #856404;'
}

四、高级优化技巧

4.1 首行缩进

中文排版习惯首行缩进两字符,这能显著提升阅读的正式感。

方案一:通过 tag-style 配置(推荐)

javascript 复制代码
const tagStyle = {
  p: 'margin: 24rpx 0; text-align: justify; letter-spacing: 1rpx; text-indent: 2em;'
}

方案二:正则预处理

如果后端返回的富文本结构复杂,可以在渲染前进行预处理:

javascript 复制代码
function formatRichText(html) {
  // 给所有 p 标签添加首行缩进样式
  html = html.replace(/<p([^>]*)>/gi, '<p$1 style="text-indent: 2em;">')
  return html
}

4.2 深色模式适配

随着深色模式的普及,富文本样式也需要适配。

javascript 复制代码
export default {
  data() {
    return {
      isDark: false,
      tagStyle: {}
    }
  },
  onLoad() {
    this.checkDarkMode()
    this.initTagStyle()
  },
  methods: {
    checkDarkMode() {
      const sysInfo = uni.getSystemInfoSync()
      this.isDark = sysInfo.theme === 'dark'
    },
    initTagStyle() {
      if (this.isDark) {
        this.tagStyle = this.getDarkTagStyle()
      } else {
        this.tagStyle = this.getLightTagStyle()
      }
    },
    getLightTagStyle() {
      return {
        body: 'color: #333; background: #fff;',
        p: 'color: #333;',
        h1: 'color: #1a1a1a;',
        blockquote: 'background: #f8f9fa; color: #555;',
        // ... 其他浅色模式样式
      }
    },
    getDarkTagStyle() {
      return {
        body: 'color: #e5e7eb; background: #1a1a1a;',
        p: 'color: #d1d5db;',
        h1: 'color: #f9fafb;',
        blockquote: 'background: #2d2d2d; color: #9ca3af; border-left-color: #60a5fa;',
        // ... 其他深色模式样式
      }
    }
  }
}

4.3 字号调节功能

为不同视力的用户提供字号调节,是提升体验的加分项。

vue 复制代码
<template>
  <view class="article-page">
    <!-- 字号调节工具栏 -->
    <view class="font-toolbar">
      <text @tap="decreaseFont">A-</text>
      <text @tap="resetFont">默认</text>
      <text @tap="increaseFont">A+</text>
    </view>
    
    <!-- 富文本内容 -->
    <mp-html
      :content="htmlContent"
      :tag-style="currentTagStyle"
    />
  </view>
</template>

<script>
const BASE_FONT_SIZE = 30 // 基础字号 rpx
const FONT_STEP = 2 // 每次调整步长

export default {
  data() {
    return {
      fontSizeOffset: 0,
      baseTagStyle: {
        // 基础样式配置
      }
    }
  },
  computed: {
    currentTagStyle() {
      const offset = this.fontSizeOffset
      const scale = 1 + offset * FONT_STEP / BASE_FONT_SIZE
      
      // 根据比例动态计算各元素字号
      return {
        body: `font-size: ${BASE_FONT_SIZE + offset * FONT_STEP}rpx;`,
        p: `font-size: ${BASE_FONT_SIZE + offset * FONT_STEP}rpx;`,
        h1: `font-size: ${Math.round(44 * scale)}rpx;`,
        h2: `font-size: ${Math.round(38 * scale)}rpx;`,
        // ... 其他元素
      }
    }
  },
  methods: {
    increaseFont() {
      if (this.fontSizeOffset < 5) {
        this.fontSizeOffset++
      }
    },
    decreaseFont() {
      if (this.fontSizeOffset > -3) {
        this.fontSizeOffset--
      }
    },
    resetFont() {
      this.fontSizeOffset = 0
    }
  }
}
</script>

4.4 图片预览优化

mp-html 自带图片点击事件,但我们可以进一步优化预览体验:

javascript 复制代码
export default {
  methods: {
    onImageTap(e) {
      const { src, imgs } = e.detail
      
      // 1. 先获取所有图片的真实地址(可能是相对路径)
      const absoluteImgs = imgs.map(img => this.resolveImageUrl(img))
      const currentSrc = this.resolveImageUrl(src)
      
      // 2. 调用原生预览
      uni.previewImage({
        current: currentSrc,
        urls: absoluteImgs,
        indicator: 'number',
        loop: true
      })
    },
    resolveImageUrl(url) {
      // 处理相对路径
      if (url.startsWith('http')) {
        return url
      }
      return 'https://your-cdn.com/' + url.replace(/^\//, '')
    }
  }
}

五、性能优化

5.1 内容预处理

在渲染前对 HTML 进行清洗和优化,减少渲染负担:

javascript 复制代码
function optimizeHtml(html) {
  if (!html) return ''
  
  // 1. 移除多余的空白标签
  html = html.replace(/<p>\s*<\/p>/gi, '')
  html = html.replace(/<div>\s*<\/div>/gi, '')
  
  // 2. 移除多余的 style 属性(如果统一用 tag-style 管理)
  // html = html.replace(/\s+style="[^"]*"/gi, '')
  
  // 3. 统一图片宽度
  html = html.replace(/<img([^>]*)width="[^"]*"([^>]*)>/gi, '<img$1$2>')
  html = html.replace(/<img([^>]*)style="[^"]*"([^>]*)>/gi, '<img$1$2>')
  
  // 4. 转换相对路径为绝对路径
  html = html.replace(/<img([^>]*)src="\/([^"]*)"([^>]*)>/gi, 
    '<img$1src="https://your-cdn.com/$2"$3>')
  
  return html
}

5.2 长内容分段渲染

对于超长文章,可以采用分段渲染的策略:

javascript 复制代码
export default {
  data() {
    return {
      renderedContent: '',
      fullContent: '',
      isLoading: false
    }
  },
  onLoad() {
    this.loadArticle()
  },
  methods: {
    async loadArticle() {
      this.isLoading = true
      
      // 模拟加载文章
      const res = await this.fetchArticle()
      this.fullContent = res.content
      
      // 先渲染前半部分
      const halfLength = Math.floor(this.fullContent.length / 2)
      this.renderedContent = this.fullContent.substring(0, halfLength)
      
      // 延迟渲染后半部分
      setTimeout(() => {
        this.renderedContent = this.fullContent
        this.isLoading = false
      }, 300)
    }
  }
}

5.3 避免频繁更新

富文本组件的渲染成本较高,应避免频繁更新 content:

javascript 复制代码
// ❌ 不好的做法:每次数据变化都更新
watch: {
  articleContent(newVal) {
    this.htmlContent = newVal
  }
}

// ✅ 好的做法:批量更新或防抖
import { debounce } from 'lodash'

export default {
  created() {
    this.updateContent = debounce(this.updateContent, 100)
  },
  methods: {
    updateContent(content) {
      this.htmlContent = content
    }
  }
}

六、常见问题与解决方案

6.1 样式不生效问题

问题 :在页面的 <style scoped> 中写的样式对富文本内部不生效。

原因 :scoped 样式会加上 data-v-xxx 属性前缀,而富文本内部的元素是动态生成的,没有这个属性。

解决方案

  1. 优先使用 tag-style 配置(推荐)
  2. 使用深度选择器 :deep()::v-deep
  3. 单独写一个非 scoped 的 style 块
vue 复制代码
<style scoped>
.article-container {
  padding: 24rpx;
}
</style>

<style>
/* 富文本内部样式,不使用 scoped */
.article-container .p {
  /* 注意:mp-html 的类名是小写标签名 */
}
</style>

6.2 图片超出屏幕宽度

问题:部分图片带有固定宽度,导致横向滚动。

解决方案:在渲染前用正则处理图片标签:

javascript 复制代码
function fixImageWidth(html) {
  // 移除 img 标签的 width 和 height 属性
  html = html.replace(/<img([^>]*)\s+width="[^"]*"([^>]*)>/gi, '<img$1$2>')
  html = html.replace(/<img([^>]*)\s+height="[^"]*"([^>]*)>/gi, '<img$1$2>')
  
  // 移除 style 中的 width 和 height
  html = html.replace(
    /<img([^>]*)\s+style="([^"]*)"([^>]*)>/gi,
    (match, before, style, after) => {
      const newStyle = style
        .replace(/width:\s*[^;]+;?/gi, '')
        .replace(/height:\s*[^;]+;?/gi, '')
      return `<img${before} style="${newStyle}"${after}>`
    }
  )
  
  return html
}

6.3 表格宽度溢出

问题:表格内容太多导致横向溢出。

解决方案:给表格外层包裹一个可滚动的容器:

javascript 复制代码
function wrapTableWithScroll(html) {
  return html.replace(
    /<table([^>]*)>/gi,
    '<div style="overflow-x: auto; -webkit-overflow-scrolling: touch; margin: 24rpx 0;"><table$1>'
  ).replace(
    /<\/table>/gi,
    '</table></div>'
  )
}

6.4 视频无法播放

问题:富文本中的 video 标签在小程序中无法正常播放。

解决方案:mp-html 支持视频扩展,需要额外引入视频播放器组件:

vue 复制代码
<mp-html
  :content="htmlContent"
  :use-video="true"
/>

七、完整示例代码

以下是一个经过生产环境验证的完整配置,可直接复制使用:

javascript 复制代码
// utils/richTextConfig.js

export const defaultTagStyle = {
  // 基础排版
  body: 'font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", "Microsoft YaHei", sans-serif; font-size: 30rpx; line-height: 1.8; color: #333; word-break: break-word;',
  
  // 段落
  p: 'margin: 24rpx 0; text-align: justify; letter-spacing: 1rpx; text-indent: 2em;',
  
  // 标题
  h1: 'font-size: 44rpx; font-weight: 600; margin: 48rpx 0 24rpx; line-height: 1.4; color: #1a1a1a; text-indent: 0;',
  h2: 'font-size: 38rpx; font-weight: 600; margin: 40rpx 0 20rpx; line-height: 1.4; color: #1a1a1a; text-indent: 0;',
  h3: 'font-size: 34rpx; font-weight: 600; margin: 32rpx 0 16rpx; line-height: 1.5; color: #222; text-indent: 0;',
  h4: 'font-size: 32rpx; font-weight: 600; margin: 28rpx 0 14rpx; line-height: 1.5; color: #222; text-indent: 0;',
  
  // 图片
  img: 'max-width: 100%; height: auto; display: block; margin: 24rpx auto; border-radius: 12rpx; box-sizing: border-box;',
  
  // 引用
  blockquote: 'margin: 32rpx 0; padding: 24rpx 28rpx; background: #f8f9fa; border-left: 8rpx solid #4a90e2; border-radius: 0 12rpx 12rpx 0; color: #555; font-size: 28rpx; line-height: 1.7; text-indent: 0;',
  'blockquote p': 'margin: 12rpx 0; text-indent: 0;',
  
  // 代码
  code: 'background: #f6f8fa; padding: 4rpx 12rpx; border-radius: 8rpx; font-family: "SF Mono", Monaco, "Courier New", monospace; font-size: 26rpx; color: #e36209; text-indent: 0;',
  pre: 'background: #282c34; color: #abb2bf; padding: 28rpx; border-radius: 12rpx; overflow-x: auto; margin: 24rpx 0; font-size: 26rpx; line-height: 1.6; text-indent: 0;',
  'pre code': 'background: transparent; padding: 0; color: inherit; font-size: inherit;',
  
  // 表格
  table: 'width: 100%; border-collapse: collapse; margin: 24rpx 0; font-size: 26rpx; text-indent: 0;',
  th: 'background: #f6f8fa; font-weight: 600; text-align: left; padding: 16rpx 20rpx; border: 1rpx solid #e5e7eb; color: #374151;',
  td: 'padding: 16rpx 20rpx; border: 1rpx solid #e5e7eb; color: #4b5563;',
  'tr:nth-child(even)': 'background: #fafbfc;',
  
  // 列表
  ul: 'margin: 20rpx 0; padding-left: 48rpx;',
  'ul li': 'margin: 12rpx 0; line-height: 1.7; list-style-type: disc;',
  ol: 'margin: 20rpx 0; padding-left: 48rpx;',
  'ol li': 'margin: 12rpx 0; line-height: 1.7; list-style-type: decimal;',
  
  // 其他元素
  hr: 'border: none; height: 2rpx; background: linear-gradient(90deg, transparent, #e5e7eb, transparent); margin: 40rpx 0;',
  strong: 'font-weight: 600; color: #1a1a1a;',
  a: 'color: #4a90e2; text-decoration: none; border-bottom: 1rpx solid rgba(74, 144, 226, 0.3);',
  mark: 'background: #fff3cd; padding: 2rpx 8rpx; border-radius: 6rpx; color: #856404;'
}

// HTML 预处理函数
export function formatRichText(html) {
  if (!html) return ''
  
  // 移除空标签
  html = html.replace(/<p>\s*(<br\s*\/?>)?\s*<\/p>/gi, '')
  
  // 图片自适应(移除固定宽高)
  html = html.replace(/<img([^>]*)\s+width="[^"]*"([^>]*)>/gi, '<img$1$2>')
  html = html.replace(/<img([^>]*)\s+height="[^"]*"([^>]*)>/gi, '<img$1$2>')
  
  // 表格外包滚动容器
  html = html.replace(
    /<table([^>]*)>/gi,
    '<div style="overflow-x: auto; -webkit-overflow-scrolling: touch;"><table$1>'
  ).replace(/<\/table>/gi, '</table></div>')
  
  return html
}

使用方式:

vue 复制代码
<template>
  <view class="article-page">
    <mp-html
      :content="formattedContent"
      :tag-style="tagStyle"
      :lazy-load="true"
      :img-mode="'widthFix'"
      @imgtap="onImageTap"
      @load="onLoad"
    />
  </view>
</template>

<script>
import { defaultTagStyle, formatRichText } from '@/utils/richTextConfig.js'

export default {
  data() {
    return {
      htmlContent: '',
      tagStyle: defaultTagStyle
    }
  },
  computed: {
    formattedContent() {
      return formatRichText(this.htmlContent)
    }
  },
  methods: {
    onImageTap(e) {
      uni.previewImage({
        current: e.detail.src,
        urls: e.detail.imgs
      })
    },
    onLoad() {
      console.log('富文本渲染完成')
    }
  }
}
</script>

<style scoped>
.article-page {
  padding: 24rpx 32rpx;
  background: #fff;
  min-height: 100vh;
}
</style>

八、总结

打造优雅的小程序富文本展示效果,核心在于以下几点:

  1. 选对方案:复杂场景优先使用 mp-html,简单场景用原生 rich-text
  2. 精细排版:行高 1.8、字间距 1rpx、两端对齐、首行缩进,这些细节决定质感
  3. 元素美化:引用块、代码块、表格、列表,每个元素都需要单独优化
  4. 图片优化:自适应、圆角、懒加载、预览功能,缺一不可
  5. 性能优化:内容预处理、避免频繁更新,保证流畅体验
  6. 体验增强:深色模式、字号调节,让不同用户都能舒适阅读

富文本优化看似是小事,但正是这些细节的积累,才能打造出真正让用户感到「优雅」的阅读体验。希望本文的方案能帮助你在项目中实现高质量的富文本展示。


参考资料: