uni-app 富文本 小程序 富文本 (微信小程序、支付宝小程序、百度小程序)直接套用pc端富文本问题解析

微信跟百度 直接使用 u-parse组件,效果还是不错的,注意一点是a标签的复制提示语,自己需要uni.hideLoading()一下,再重置。

支付宝相对复杂一点,采用原生rich-text 标签,搭配官方推荐的mini-html-parser2,处理富文本。

同时需要处理一下pc端可正常展示,但是小程序富文本不支持的部分:

let parseData = this.docBody.replace(/(\t|\n)/g,''); // 去掉所有富文本中的空格,换行等
parseData = parseData.replace(/(<script).*?(\/script>)/, '') // 替换掉会引起报错的script标签。
parseData = parseData.replace(/(<html>)|(<\/html>)/g, '') // 替换掉会引起报错的html标签。
parseData = parseData.replace(/(<body>)|(<\/body>)/g, '') // 替换掉会引起报错的html标签。
parseData = parseData.replace(/(&#xa0;)/g, '') // 替换掉会引起报错的html标签。
parseData = parseData.replace(/(<p><!--\[if !mso])[\s\S]*?(<!\[endif]--><\/p>)/g, '') // 替换掉会引起报错的标签。
parseData = parseData.replace(/(<style).*?(\/style>)/, '') // 替换掉会引起报错的script标签。
// <!--[if gte mso 9]> <![endif]-->
// <!--[if supportMisalignedColumns]--> <!--[endif]-->
parseData = parseData.replace(/(<!--\[if).*?(endif]-->)/g, '') // 替换掉会引起报错的标签。

直接上组件代码

<template>
  <view class="wjw-rich-text">
    <!-- #ifdef MP-ALIPAY -->
    <rich-text :nodes="parseDocBody" @tap="handleOnTap"></rich-text>
    <!-- #endif -->
    <!-- #ifndef MP-ALIPAY -->
    <u-parse :content="parseDocBody" @linktap="linktap" :copyLink="false"></u-parse>
    <!-- #endif -->
  </view>
</template>
<script>
import parse from 'mini-html-parser2';
const HTML_A_TAG = 'a';

export default {
  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标签。
        parseData = parseData.replace(/(<html>)|(<\/html>)/g, '') // 替换掉会引起报错的html标签。
        parseData = parseData.replace(/(<body>)|(<\/body>)/g, '') // 替换掉会引起报错的html标签。
        parseData = parseData.replace(/(&#xa0;)/g, '') // 替换掉会引起报错的html标签。
        parseData = parseData.replace(/(<p><!--\[if !mso])[\s\S]*?(<!\[endif]--><\/p>)/g, '') // 替换掉会引起报错的标签。
        parseData = parseData.replace(/(<style).*?(\/style>)/, '') // 替换掉会引起报错的script标签。
        // <!--[if gte mso 9]> <![endif]-->
        // <!--[if supportMisalignedColumns]--> <!--[endif]-->
        parseData = parseData.replace(/(<!--\[if).*?(endif]-->)/g, '') // 替换掉会引起报错的标签。
        // #ifndef MP-ALIPAY
        this.parseDocBody = parseData
        // #endif
        // #ifdef MP-ALIPAY
        try {
          parse(parseData, (err, nodes) => {
            if (err) {
              console.log('parseData-err', 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)// 递归处理a标签
              this.parseDocBody = transferNodes
            }
          })
        } catch (err) {
          this.parseDocBody = ''
        }
        // #endif   
      },
      immediate: true,
      deep: true
    }
  },
  methods: {
  /**
   * 
   * @param {跳转webview} e 
   */
    navigate(e) {
      this.$util.navigateTo({
        url: `/pages/publicPages/webView?url=${e}`
      })
    },
    handleNavigate(href) {
      if (href.includes('https://www.baidu.com')) {
        this.$util.showToast('跳转中...', this)
        this.navigate(href)
        return true
      }
      return false
    },
    linktap(e) {
      const { href } = e
      setTimeout(()=> {
        uni.setClipboardData({
          data: href,
          success: () => {
            uni.hideLoading()
            if (this.handleNavigate(href)) return
            this.$util.showToast('链接已复制, 请到浏览器中查看!', this)
          }
        });
      })
    },
    handleOnTap(e) {
      const {
        detail: { marks }, // 获取自定义的marks
      } = e
      const { name, href } = marks || {} // 
      if (name === HTML_A_TAG && href) { // 判断是否是 a 标签,同时有 href 链接
        uni.setClipboardData({
          data: href,
          success: () => {
            if (this.handleNavigate(href)) return
            this.$util.showToast('链接已复制, 请到浏览器中查看!', this)
          }
        });
      }
    },
  }
}
</script>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值