vue使用富文本编辑器之任意位置视频上传,且在uni项目中正常回显

由于富文本编辑器的视频上传组件需要自定义,下面先定义富文本组件中的视频上传

富文本编辑器使用

html部分

  <div>
    <el-upload
      :action="uploadImgUrl"
      :before-upload="handleBeforeUpload"
      :on-success="handleUploadSuccess"
      :on-error="handleUploadError"
      name="file"
      :show-file-list="false"
      :headers="headers"
      style="display: none"
      ref="upload"
      v-if="this.type == 'url'"
    >
    </el-upload>
    <div class="editor" ref="editor" :style="styles" @paste="onPaste($event)"></div>

    <!-- 自定义视频上传 -->
    <el-dialog :close-on-click-modal="false" width="50%" style="margin-top: 1px" title="视频上传"
               :visible.sync="videoForm.show" append-to-body
    >
      <el-tabs v-model="videoForm.activeName">
        <el-tab-pane label="添加视频链接" name="first">
          <el-input v-model="videoForm.videoLink" placeholder="请输入视频链接" clearable></el-input>
          <el-button type="primary" size="small" style="margin: 20px 0px 0px 0px "
                     @click="insertVideoLink(videoForm.videoLink)"
          >确认
          </el-button>
        </el-tab-pane>
        <el-tab-pane label="本地视频上传" name="second">
          <el-upload v-loading="loading" style="text-align: center;" drag :action="uploadVideoConfig.uploadUrl"
                     accept="video/*" :name="uploadVideoConfig.name" :headers="headers"
                     name="file"
                     :before-upload="onBeforeUploadVideo"
                     :on-success="onSuccessVideo" :on-error="onErrorVideo" :multiple="false"
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
            <div class="el-upload__tip" slot="tip">只能上传MP4文件,且不超过{{ uploadVideoConfig.maxSize }}M</div>
          </el-upload>
        </el-tab-pane>
      </el-tabs>
    </el-dialog>
  </div>

可以在data中声明富文本配置项,后续方便初始化富文本组件

     options: {
        theme: 'snow',
        bounds: document.body,
        debug: 'warn',
        modules: {
          // 工具栏配置
          toolbar: {
            container: [
              ['bold', 'italic', 'underline', 'strike'],       // 加粗 斜体 下划线 删除线
              ['blockquote', 'code-block'],                    // 引用  代码块
              [{ list: 'ordered' }, { list: 'bullet' }],       // 有序、无序列表
              [{ indent: '-1' }, { indent: '+1' }],            // 缩进
              [{ size: ['small', false, 'large', 'huge'] }],   // 字体大小
              [{ header: [1, 2, 3, 4, 5, 6, false] }],         // 标题
              [{ color: [] }, { background: [] }],             // 字体颜色、字体背景颜色
              [{ align: [] }],                                 // 对齐方式
              ['clean'],                                       // 清除文本格式
              ['link', 'image', 'video']                       // 链接、图片、视频
            ],
            handlers: {
              'video': () => {
                // 覆盖默认的上传视频,点击视频图标,显示弹窗
                _self.videoForm.show = true
                this.range = this.$refs.editor.quill.selection.savedRange.index
              },
              'image': (value) => {
                document.querySelector('.avatar-uploader input').click()
                this.range = this.$refs.editor.quill.selection.savedRange.index
              }
            }
          }
        },
        placeholder: '请输入内容',
        readOnly: this.readOnly
      },

初始化组件

    init() {
      const editor = this.$refs.editor
      this.Quill = new Quill(editor, this.options)
      // 如果设置了上传地址则自定义图片上传事件
      let toolbar = this.Quill.getModule('toolbar')
      toolbar.addHandler('video', () => {
        // 覆盖默认的上传视频,点击视频图标,显示弹窗
        this.videoForm.show = true
        this.range = this.Quill.getSelection().index
      })
      if (this.type == 'url') {
        toolbar.addHandler('image', (value) => {
          if (value) {
            this.$refs.upload.$children[0].$refs.input.click()
          } else {
            this.quill.format('image', false)
          }
        })
      }
      this.Quill.pasteHTML(this.currentValue)
      this.Quill.on('text-change', (delta, oldDelta, source) => {
        const html = this.$refs.editor.children[0].innerHTML
        const text = this.Quill.getText()
        const quill = this.Quill
        this.currentValue = html
        this.$emit('input', html)
        this.$emit('on-change', { html, text, quill })
      })
      this.Quill.on('text-change', (delta, oldDelta, source) => {
        this.$emit('on-text-change', delta, oldDelta, source)
      })
      this.Quill.on('selection-change', (range, oldRange, source) => {
        this.$emit('on-selection-change', range, oldRange, source)
      })
      this.Quill.on('editor-change', (eventName, ...args) => {
        this.$emit('on-editor-change', eventName, ...args)
      })
    },

自定义视频上传方法

    insertVideoLink(videoLink) {
      if (!videoLink) return this.$message.error('视频地址不能为空!')
      this.videoForm.show = false
      let quill = this.Quill
      // 获取富文本
      let range = quill.getSelection()
      // 获取光标位置:当编辑器中没有输入文本时,这里获取到的 range 为 null
      let index = range ? range.index : this.range
      // 在光标所在位置 插入视频
      quill.insertEmbed(index, 'video', videoLink)
      // 调整光标到最后
      quill.setSelection(index + 1)
    },
    // el-文件上传组件
    onBeforeUploadVideo(file) {
      this.loading = true
      let acceptArr = ['video/mp4']
      const isVideo = acceptArr.includes(file.type)
      const isLt1M = file.size / 1024 / 1024 < this.uploadVideoConfig.maxSize
      if (!isVideo) {
        this.hideLoading()
        this.$message.error('只能上传mp4格式文件!')
      }
      if (!isLt1M) {
        this.hideLoading()
        this.$message.error(`上传文件大小不能超过 ${this.uploadVideoConfig.maxSize}MB!`)
      }
      return isLt1M && isVideo
    },
    // 文件上传成功时的钩子
    onSuccessVideo(res) {
      this.hideLoading()
      if (res.code === 200) {
        this.insertVideoLink(res.data.url)
      } else {
        this.$message.error(res.msg)
      }
    },
    // 文件上传失败时的钩子
    onErrorVideo() {
      this.hideLoading()
      this.$message.error('上传失败')
    }

需要注意的是当点击上传视频时,光标会失去焦点,所以在视频上传完毕后回显到富文本中时需要获取插入的光标

uni中使用mp-html组件,且需要对富文本内容进行处理

	info= info.replace(/<iframe[^>]*src=["']([^"']*)["'][^>]*>/g,
						'<video  src="$1" autoplay style="height: 200px;width:100%" > '
					);
	const reg = new RegExp('</iframe>', "g")
	info = info.replace(reg,'</video>');
  • 17
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值