wangEditor+小程序展示富文本


1、需求:要在小程序中展示新手指引富文本,吃饱没事做的后端拉着我要弄一个pc端编辑富文本的页面。

2、思路:pc端wangEditor怼上去就好,比较注意的就是自定义的视频上传,小程序端要注意的就是视频不能用微信自带的rich-text去展示

3、实现

视频自定义上传

.vue

        createWangeditor() {
            let _this = this
            this.editor = new E(this.$refs.guide)
            this.editor.config.height = this.$refs.guide.offsetHeight - 42
            this.editor.config.uploadImgShowBase64 = true
            this.editor.config.showLinkVideo = false
            this.editor.config.customUploadVideo = function(resultFiles, insertVideoFn) {
                // resultFiles 是 input 中选中的文件列表
                // insertVideoFn 是获取视频 url 后,插入到编辑器的方法
                let file = resultFiles[0]
                const form = new FormData()
                form.append('file', file)
                form.append('displayName', file.name)
                form.append('busiType', 'priceChange')
                _this.ajax
                    .post('/com/file/upload', form, {
                        'Content-Type': 'multipart/form-data'
                    })
                    .then(res => {
                        console.log(res)
                        // 上传视频,返回结果,将视频地址插入到编辑器中
                        insertVideoFn(res.fileUrl)
                    })
            }
            this.editor.create()
        }

小程序展示组件

richtext.js

// components/richtext/richtext.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    contentText: {
      type: String,
      default: '',
      observer: function (newVal) {
        this.deCodeRich(newVal)
      }
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    content: []
  },

  /**
   * 组件的方法列表
   */
  methods: {
    deCodeRich(str) {
      // 移除iframe
      // const iframeReg = /|><\/iframe>){1}/g   //原本
      const iframeReg = new RegExp('|><\\/iframe>){1}', 'g')
      str = str.replace(iframeReg, '')
      // 获取video
      // const videoReg = /|><\/video>){1}/g //原本
      const videoReg = new RegExp('|><\\/video>){1}', 'g')
      const videoMatch = (str.match(videoReg) || []).map(e => ({ type: 'video', text: e }))
      // 获取audio
      // const audioReg = /{1}/g //原本
      const audioReg = new RegExp('{1}', 'g')
      const audioMatch = (str.match(audioReg) || []).map(e => ({ type: 'audio', text: e }))
      const matchAry = [].concat(...videoMatch, ...audioMatch)
      let richData = []
      if (matchAry.length > 0) {
        // 匹配到
        for (let m of matchAry) {
          let splitData = str.split(m.text)
          let restOfStr = '' //剩余字符串
          const notMiddle = (splitData[0] ? 1 : 0) ^ (splitData[splitData.length - 1] ? 1 : 0)
          if (!notMiddle) {
            let newSplitData = []
            splitData.forEach((d, i) => {
              newSplitData.push(d)
              if (i !== splitData.length - 1) {
                newSplitData.push('')
              }
            })
            splitData = newSplitData
          }
          const newData = splitData.map(s => {
            if (!s) {
              // 获取 src&style
              // /(?<=src=")[\s\S]*?(?=")/ 原本
              // /(?<=style=")[\s\S]*?(?=")/ 原本
              const srcReg = new RegExp('(?<=src=")[\\s\\S]*?(?=")')
              const styleReg = new RegExp('(?<=style=")[\\s\\S]*?(?=")')
              let src = m.text.match(srcReg)
              let style = m.text.match(styleReg)
              return { type: m.type, src: src ? src[0] : null, style: style ? style[0] : null }
            } else {
              restOfStr += s
              return s
            }
          })
          str = restOfStr
          if (newData.length > 1) {
            //内容正常
            const rIndex = richData.findIndex(rich => typeof rich === "string")
            rIndex !== -1 ? richData[rIndex] = newData : richData = newData
            // 展开二维数组
            richData = Array.prototype.concat.apply([], richData)
          }
          // console.log(richData);
        }
      } else {
        //匹配不到
        richData.push(str)
      }
      this.setData({
        content: richData.map(e => {
          if (typeof e === "string") {
            return { type: 'rich', rich: e }
          } else return Object.assign(e)
        })
      })
    }
  }
})

richtext.wxml

<block wx:for="{{content}}" wx:key="index">
    <rich-text wx:if="{{item.type==='rich'}}" nodes="{{item.rich}}" />
    <video wx:if="{{item.type==='video'}}" src="{{item.src}}" style="{{item.style}}" />
    <view style="text-align:center" wx:if="{{item.type==='audio'}}">
        <audio
         name="{{title}}"
         author="{{title}}"
         controls="{{true}}"
         src="{{item.src}}"
         style="{{item.style}}"
        />
    view>
block>