开始之前先了解几个插件:

npm install mini-html-parser2 --save
“mini-html-parser2”: “^0.3.0”,
mini-html-parser2(专为支付宝研制,将字符串中标签,一一转化为array,供支付宝小程序 的rich-text nodes 使用)

feng-parse(一款专门为解决百度小程序诞生的富文本插件,可完美兼容微信小程序)

先说说遇到的问题:

  1. pc端的富文本不可避免的有a标签,a标签在小程序里跳转的话,还需要在对应网址进行安全认证(放一个txt,能读到就行), 借助feng-parse的思路,点击链接实现复制操作,粘贴出来再浏览器端阅读。
  2. 部分富文本有携带script标签,组件处理会报错,需要正则化干掉。
  3. 正则化时,需要先将富文本中多余的 空格和回车去掉,不然匹配可能会出问题。

上代码:

<template>
  <view class="rich-text-class">
    <!-- #ifdef MP-ALIPAY -->
    <rich-text :nodes="parseDocBody" @tap="handleOnTap"></rich-text>
    <!-- #endif -->
    <!-- #ifndef MP-ALIPAY -->
    <u-parse :content="parseDocBody"></u-parse>
    <!-- #endif -->
  </view>
</template>

<script>
import uParse from "@/components/feng-parse/parse.vue"
import parse from 'mini-html-parser2';
const HTML_A_TAG = 'a';

export default {
  comments: {
    uParse
  },
  props: {
    docBody: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      parseDocBody: ''
    }
  },
  watch: {
    docBody: {
      handler(val) {
        let parseData = this.docBody.replace(/(\t|\n)/g,''); // 去掉所有富文本中的空格,换行等
        parseData = parseData.replace(/(<script).*?(\/script>)/, '') // 替换掉会引起报错的script标签。
        // #ifndef MP-ALIPAY
        this.parseDocBody = parseData // 百度,微信的富文本直接采用feng-parse,自带复制功能
        // #endif
        // #ifdef MP-ALIPAY
        try {
          parse(parseData, (err, nodes) => {
            if (err) {
              console.log('parseData', parseData)
            }
            if (!err) {
              const recursion = (list) => {
                return list.map(item => {
                  const { children, name, attrs } = item;
                  // 这里没有处理 children
                  if (name === HTML_A_TAG) { // 这里假定 原本的htmlstring中 a标签为原本跳转的元素
                    item.marks = { ...attrs, name: HTML_A_TAG }; // 小程序中不支持 a标签的href属性,先把对应的href 属性放在marks中
                  }
                  if (children) {
                    recursion(children)
                  }
                  return item
                })
              }
              const transferNodes =  recursion(nodes)
              this.parseDocBody = transferNodes
            }
          })
        } catch (err) {
          this.parseDocBody = ''
        }
        // #endif   
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    handleOnTap(e) {
      const {
        detail: { marks }, // 获取自定义的marks
      } = e
      const { name, href } = marks || {} // 
      if (name === HTML_A_TAG && href) { // 判断是否是 a 标签,同时有 href 链接
        uni.setClipboardData({
          data: href,
          success: () => {
            uni.showToast({
              title: '链接已复制',
              icon: 'success'
            })
          }
        });
      }
    },
  }
}
</script>

更多推荐