uni-app sp-editor 上传视频时遇到的问题

65 阅读3分钟

sp-editor 在上传视频时 在官方文档中是没有示例的,只要在下载了 hbuilderx 插件市场中的插件 官方富文本编辑器editor组件改良扩展优化版示例 中才有示例。

具体使用如下 在实际使用过程中 当导 sp-editor 插件时 只会导入编辑的部分,实际上展示的部分也需要导入,展示内容的获取方式为 去 插件市场搜索 mp-html 导入就可以正常展示了

<template>
  <view class="example1">
    <view class="editor">
      <sp-editor
        editorId="editor"
        :toolbar-config="toolbarConfig"
        @input="inputOver"
        @upinImage="upinImage"
        @upinVideo="upinVideo"
        @init="initEditor"
        @overMax="overMax"
        @exportHtml="exportHtml"
        @addLink="addLink"
      ></sp-editor>
    </view>
  </view>
</template>

<script>
    import { convertImgStylesToAttributes, handleHtmlWithVideo } from '@/uni_modules/sp-editor/utils'
    export default {
      data() {
        return {
          editorIns: null,
          toolbarConfig: {
            // excludeKeys: ['direction', 'date', 'lineHeight', 'letterSpacing', 'listCheck'],
            iconSize: '20px',
            iconColumns: 10
          },
          mediaQueryOb: null // 响应式媒体查询
        }
      },
      mounted() {
        this.testMediaQueryObserver()
      },
      destroyed() {
        this.mediaQueryOb.disconnect() //组件销毁时停止媒体查询监听
        this.mediaQueryOb = null
        console.log('==== destroyed :')
      },
      methods: {
        /**
         * 媒体查询 - 响应式处理一些东西
         */
        testMediaQueryObserver() {
          this.mediaQueryOb = uni.createMediaQueryObserver(this)
          this.mediaQueryOb.observe(
            {
              minWidth: 0, //页面最小宽度 0px
              maxWidth: 500 //页面宽度最大 500px
            },
            (matches) => {
              console.log('==== 开启媒体查询 :', matches)
              if (matches) {
                // 页面宽度在0-500px时
                this.toolbarConfig.iconColumns = 12
              } else {
                this.toolbarConfig.iconColumns = 16
              }
            }
          )
        },
        /**
         * 获取输入内容
         * @param {Object} e {html,text} 内容的html文本,和text文本
         */
        inputOver(e) {
          console.log('==== inputOver :', e)
        },
        /**
         * 超出最大内容限制
         * @param {Object} e {html,text} 内容的html文本,和text文本
         */
        overMax(e) {
          console.log('==== overMax :', e)
        },
        /**
         * 编辑器就绪
         * @param {Object} editor 编辑器实例,你可以自定义调用editor实例的方法
         * @tutorial editor组件 https://uniapp.dcloud.net.cn/component/editor.html#editor-%E7%BB%84%E4%BB%B6
         * @tutorial 相关api https://uniapp.dcloud.net.cn/api/media/editor-context.html
         */
        initEditor(editor) {
          this.editorIns = editor // 保存编辑器实例
          this.preRender()
        },
        preRender() {
          // 初始化编辑器内容
          uni.showLoading({
            title: '数据加载中...'
          })
          setTimeout(() => {
            const htmlContent = ``
            const handleHtml = convertImgStylesToAttributes(htmlContent)
            console.log(handleHtml);
            this.editorIns.setContents({
              html: handleHtml
            })
            uni.hideLoading()
          }, 1000)
        },
        /**
         * 直接运行示例工程插入图片无法正常显示的看这里
         * 因为插件默认采用云端存储图片的方式
         * 以$emit('upinImage', tempFiles, this.editorCtx)的方式回调
         * @param {Object} tempFiles
         * @param {Object} editorCtx
         */
        upinImage(tempFiles, editorCtx) {
          /**
           * 本地临时插入图片预览
           * 注意:这里仅是示例本地图片预览,因为需要将图片先上传到云端,再将图片插入到编辑器中
           * 正式开发时,还请将此处注释,并解开下面 使用 uniCloud.uploadFile 上传图片的示例方法 的注释
           * @tutorial https://uniapp.dcloud.net.cn/api/media/editor-context.html#editorcontext-insertimage
           */
          // #ifdef MP-WEIXIN
          // 注意微信小程序的图片路径是在tempFilePath字段中
          editorCtx.insertImage({
            src: tempFiles[0].tempFilePath,
            width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
            success: function () {}
          })
          // #endif

          // #ifndef MP-WEIXIN
          editorCtx.insertImage({
            src: tempFiles[0].path,
            width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
            success: function () {}
          })
          // #endif
        },
        upinVideo(tempFilePath, editorCtx) {
          // 此处tempFilePath为本地视频临时地址,请对接后端接口将视频上传后,获取真实地址,再插入到编辑器中
          // 上传视频,并获取视频真实地址(其实和上面插入图片的步骤差不多)
          const videoUrl = tempFilePath

          // 插入一张图片占位(uni-editor无法直接插入video标签,所以需要以图片占位)
          editorCtx.insertImage({
            src: 'https://img.zcool.cn/community/01055859b8e37fa8012075341db67f.gif',
            width: '80%', // 默认不建议铺满宽度100%,预留一点空隙以便用户编辑
            alt: videoUrl, // 携带视频真实地址
            success: () => {}
          })
        },
        /**
         * 导出
         * @param {string} e 导出的html内容
         */
        exportHtml(e) {
          // 若携带视频,需按需导入handleHtmlWithVideo方法处理富文本,再导出
          const temphtml = handleHtmlWithVideo(e)
          uni.navigateTo({
            url: '/pages/out/out',
            success(res) {
              res.eventChannel.emit('e-transmit-html', {
                data: temphtml
              })
            }
          })
        },
        /**
         * 添加超链接
         * @param {Object} e { text: '链接描述', href: '链接地址' }
         */
        addLink(e) {
          console.log('==== addLink :', e)
        }
      }
    }
</script>

<style lang="scss">
    .example1 {
      padding: 12px;
      box-sizing: border-box;
      // height: calc(100vh - var(--window-top));
      height: 100%;

      .header,
      .footer {
        background-color: #66ccff;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: space-evenly;
      }
      .header {
        height: 100px;
      }
      .footer {
        height: 600px;
      }

      .editor {
        // height: calc(100% - 100px);
        height: 460px;
        // 吸顶
        position: sticky;
        top: var(--window-top);
        background-color: #ffffff;
        border: 1px solid #ff0000;
      }
    }
</style>

展示部分使用示例,在示例中 mp-html 为speditor 的展示部分,如果没有这个展示部件展示中会有部分异常比较难处理

    <template>
      <view>
        <mp-html :content="htmlContent" />
      </view>
    </template>

    <script>
    export default {
      data() {
        return {
          htmlContent: ''
        }
      },
      onLoad() {
        const eventChannel = this.getOpenerEventChannel()
        eventChannel.once('e-transmit-html', (res) => {
          this.htmlContent = res.data
        })
      },
      methods: {}
    }
    </script>

<style></style>